は何かを(あなたのテーブルをと仮定するとyour_table
という名前で、日付列がthe_date
命名されます) :
with date_range as (
select min(the_date) as oldest,
max(the_date) as recent,
max(the_date) - min(the_date) as total_days
from your_table
),
all_dates as (
select oldest + level - 1 as a_date
from date_range
connect by level <= (select total_days from date_range)
)
select ad.a_date
from all_dates ad
left join your_table yt on ad.a_date = yt.the_date
where yt.the_date is null
order by ad.a_date;
編集:
WITH
句は「共通テーブル式」と呼ばれ、派生テーブル(「インラインビュー」)と同等です。
なお、第2のCTEは、単にOracleのconnect by
実装のドキュメント化されていない機能を使用して、「オンザフライ」の日付のリストを作成し
select *
from (
.....
) all_dates
join your_table ...
に似ています。
選択(私が最初と最後の日付を計算するのと同じように)を再利用すると、派生テーブルを使用するよりも少し楽になります(IMHOが読みやすくなります)。
編集2:
これは、同様に再帰CTEで行うことができます。
再帰CTEの(PostgreSQLとFirebirdのサポートするすべてのDBMSで動作するはず
with date_range as (
select min(the_date) as oldest,
max(the_date) as recent,
max(the_date) - min(the_date) as total_days
from your_table
),
all_dates (a_date, lvl) as (
select oldest as a_date, 1 as lvl
from date_range
union all
select (select oldest from date_range) + lvl, lvl + 1
from all_dates
where lvl < (select total_days from date_range)
)
select ad.a_date, lvl
from all_dates ad
left join your_table yt on ad.a_date = yt.the_date
where yt.the_date is null
order by ad.a_date;
- 準拠した多くの標準であることをしかし、recursive
というキーワードが必要です)。
再帰部分のハックselect (select oldest from date_range) + lvl, lvl + 1
に注意してください。これは必ずしも必要ではありませんが、Oracleでは再帰的なCTEのDATEに関していくつかのバグがあります。 PostgreSQLでは問題なく、次の作品:
....
all_dates (a_date, lvl) as (
select oldest as a_date, 0 as lvl
from date_range
union all
select a_date + 1, lvl + 1
from all_dates
where lvl < (select total_days from date_range)
)
....
は、私はあなたが(SQL日付別のグループと一緒に)それを行うには、カーソルを使用する必要がありますと思います。 – theglauber
これは単一のクエリである必要がありますか、それは一連のpl/sql命令ですか? –
私は単一のクエリを好むでしょうが、それがすべて可能ならばスクリプトかもしれません。 –