4

自分で書くことに成功しなかった SQL を書くための助けを得たいと思っています。

私はデータを含むテーブルを持っています:

ID 開始日 終了日
1 2000/01/01 04:30 PM 2000/01/03 06:15 AM
2 2000 年 1 月 4 日午前 8 時 10 分 2000 年 1 月 4 日午前 7 時 25 分
3 2000/01/05 11:00 AM 2000/01/06 03:45 AM

次のものを取得する必要があります。

ID 開始日 終了日
1 2000 年 1 月 1 日午後 4 時 30 分 2000 年 1 月 1 日午後 11 時 59 分
1 2000/01/02 12:00 AM 2000/01/02 11:59 PM
1 2000 年 1 月 3 日午前 12:00 2000 年 1 月 3 日午前 6:15
2 2000 年 1 月 4 日午前 8 時 10 分 2000 年 1 月 4 日午前 7 時 25 分
3 2000 年 1 月 5 日 11:00 2000 年 1 月 5 日 11:59 午後
3 2000/06/01 午前 12:00 2000/01/06 午前 3:45

つまり、日付範囲を日ごとに分割します。これはSQLでも可能ですか?

私のデータベースは Oracle 11G R2 ですが、事情により PL/SQL を使用できません。

4

2 に答える 2

7

これは SQL で行うことができます。2つのトリックがあります。1 つ目は、一連の数値を生成することです。これは、 を使用して CTE で実行できますconnect

2 つ目は、開始と終了の適切な時間を維持しながら、日付を拡張するための適切なロジックをまとめることです。

次に例を示します。

with n as (
      select level n
      from dual connect by level <= 20
     ),
     t as (
      select 1 as id, to_date('01/01/2000 4', 'mm/dd/yyyy hh') as StartDate, to_date('01/03/2000 6', 'mm/dd/yyyy hh') as EndDate from dual union all
      select 2 as id, to_date('01/04/2000 8', 'mm/dd/yyyy hh') as StartDate, to_date('01/04/2000 12', 'mm/dd/yyyy hh') as EndDate from dual union all
      select 3 as id, to_date('01/05/2000', 'mm/dd/yyyy') as StartDate, to_date('01/06/2000', 'mm/dd/yyyy') as EndDate from dual
     )
select t.id,
       (case when n = 1 then StartDate
             else trunc(StartDate + n - 1)
        end) as StartDate,
       (case when trunc(StartDate + n - 1) = trunc(enddate)
             then enddate
             else trunc(StartDate + n)
        end)
from t join
     n
     on StartDate + n - 1 <= EndDate
order by id, StartDate

これはSQLFiddleにあります。

于 2013-06-11T01:54:34.030 に答える
-1

ありがとうゴードン!私もとても助かりました。私のユニークなコメントは、結合句を次のように変更する必要があったことです。

on StartDate + n - 1 <= EndDate

に:

on trunc(StartDate + n - 1) <= trunc(EndDate)

この変更の後、それは私にとって完全に機能しました。

于 2017-03-03T16:25:51.473 に答える