次の問題を解決するのに役立つクエリを探しています。
5つのイベントがあるとします。
これらのイベントのうち3つは1月9日と重複します。これは最大の重複イベントであるため、答えは3です。
(1月10日に3つのイベントが重複していますが、同じ答えです)
メモリでこれを行っていた場合、これを行うことができます:
しかし、これには2つの問題があります。
このようなものをSQLに実装するにはどうすればよいですか?
これをSQLではなくコードで記述する方がパフォーマンスが向上する可能性があります。
コードでは、アイテムを開始日、次に終了日で並べ替えます。それらを確認し、次の項目と重複していないか確認してください。重複している場合は、オーバーラップカウンターをインクリメントして繰り返します。次のアイテムがアイテムと重複していることを確認します。表示されない場合は、次に進みます。
SQLでは、自己結合を使用してすべての重複を一覧表示できます。
これにより、すべての重複が表示されます。
select a.eventid from events a
inner join events b
on a.end > b.start and a.start < b.end
次に、それらをeventidでグループ化し、カウントを選択して、最大カウントのイベントを取得できます。
select top 1 eventid, count(*) as c
from
(select a.eventid from events a
inner join events b
on a.end > b.start and a.start < b.end)
group by eventid
order by c desc
リレーショナルデータベースのもう1つの戦略は、各暦日のレコードを含むテーブルを作成することです。これは、システムに存在しない日を特定しようとしている状況で役立ちます。計算によってデータを作成するためにデータベースに依存する代わりに、そこにあるデータを操作するほうが簡単です。
そのテーブルとイベントのテーブルを使用して、それらを結合し、いくつかの単純な集計を実行できます(SQL Server)。
create table Datelist (
HistoryDate datetime not null
)
insert into DateList (HistoryDate)
values
( '1/1/2018')
, ('1/2/2018')
...
create table event (
StartDate datetime not null
, EndDate datetime not null
)
insert into event (StartDate, EndDate)
values ('01/01/2018', '01/09/2018')
, ('01/07/2018', '01/12/2018')
, ('01/08/2018', '01/10/2018')
, ('01/10/2018', '01/15/2018')
, ('01/12/2018', '01/17/2018')
select max(c.EventCount) as maxEvents
from (
select d.HistoryDate
, count(d.HistoryDate) as EventCount
from DateList as d
inner join event as e
on d.HistoryDate between e.StartDate and e.EndDate
group by d.HistoryDate
) as c
クエリを読むのはそれほど難しくありませんが、事前設定された「DateList」テーブルの内容を理解する必要があります。サブクエリを実行して、テスト目的で各日付の実際のリストを確認できます。