4

我希望得到一些帮助来编写一些我自己没有成功编写的 SQL。

我有一张包含数据的表格:

ID 开始日期 结束日期
1 01/01/2000 04:30 PM 01/03/2000 06:15 AM
2 2000 年 1 月 4 日上午 8 点 10 分 2000 年 1 月 4 日上午 7 点 25 分
3 2000 年 1 月 5 日上午 11:00 2000 年 1 月 6 日上午 03:45

我需要得到以下信息:

ID 开始日期 结束日期
1 2000 年 1 月 1 日下午 4:30 2000 年 1 月 1 日下午 11:59
1 2000 年 1 月 2 日上午 12:00 2000 年 1 月 2 日下午 11:59
1 01/03/2000 12:00 AM 01/03/2000 06:15 AM
2 2000 年 1 月 4 日上午 8 点 10 分 2000 年 1 月 4 日上午 7 点 25 分
3 2000 年 1 月 5 日上午 11:00 2000 年 1 月 5 日晚上 11:59
3 01/06/2000 12:00 AM 01/06/2000 03:45 AM

换句话说,按天拆分日期范围。这在 SQL 中甚至可能吗?

我的数据库是 Oracle 11G R2,我担心由于情况我不能使用 PL/SQL。

4

2 回答 2

7

可以在 SQL 中执行此操作。有两个技巧。首先是生成一系列数字,您可以使用connect.

第二个是将正确的逻辑放在一起以扩展日期,同时保持正确的开始和结束时间。

下面是一个例子:

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

谢谢戈登!它也帮助了我很多。我独特的评论是我必须将 join 子句从:

on StartDate + n - 1 <= EndDate

至:

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

在此更改之后,它对我来说非常有效。

于 2017-03-03T16:25:51.473 回答