Oracle sql:在同一组中查找最小最大连续日期

时间:2016-10-12 14:43:55

标签: sql oracle gaps-and-islands

我知道问题可能解释得很糟糕,但我不知道如何解释这个问题。我有以下数据:(按日期排序)

    DATE    GROUP
    11-Oct-16   A
    12-Oct-16   A
    13-Oct-16   A
    14-Oct-16   B
    15-Oct-16   B
    16-Oct-16   A
    17-Oct-16   A
    18-Oct-16   C
    19-Oct-16   C
    20-Oct-16   C
    21-Oct-16   C
    22-Oct-16   A
    23-Oct-16   A
    24-Oct-16   A

我想查找群组的连续使用情况。我想要的结果将比我更好地解释:

    GROUP   MIN(DATE)   MAX(DATE)
    A   11-Oct-16   13-Oct-16
    B   14-Oct-16   15-Oct-16
    A   16-Oct-16   17-Oct-16
    C   18-Oct-16   21-Oct-16
    A   22-Oct-16   24-Oct-16

知道如何在oracle sql中执行此操作吗? 谢谢。

3 个答案:

答案 0 :(得分:2)

这可以是一种方式:

with test("DATE","GROUP") as
(
    select to_date('11-10-16', 'dd-mm-rr'),'A' from dual union all
    select to_date('12-10-16', 'dd-mm-rr'),'A' from dual union all
    select to_date('13-10-16', 'dd-mm-rr'),'A' from dual union all
    select to_date('14-10-16', 'dd-mm-rr'),'B' from dual union all
    select to_date('15-10-16', 'dd-mm-rr'),'B' from dual union all
    select to_date('16-10-16', 'dd-mm-rr'),'A' from dual union all
    select to_date('17-10-16', 'dd-mm-rr'),'A' from dual union all
    select to_date('18-10-16', 'dd-mm-rr'),'C' from dual union all
    select to_date('19-10-16', 'dd-mm-rr'),'C' from dual union all
    select to_date('20-10-16', 'dd-mm-rr'),'C' from dual union all
    select to_date('21-10-16', 'dd-mm-rr'),'C' from dual union all
    select to_date('22-10-16', 'dd-mm-rr'),'A' from dual union all
    select to_date('23-10-16', 'dd-mm-rr'),'A' from dual union all
    select to_date('24-10-16', 'dd-mm-rr'),'A' from dual
)
select min("DATE"), max("DATE"), "GROUP" 
from (
        select "DATE",
               "DATE" - row_number() over (partition by "GROUP" order by "DATE") as minDate,
               "GROUP"
        from test
)
group by "GROUP", minDate
order by "GROUP", minDate

内部查询构建一组连续日期的最小日期,而外部查询只是按此最小日期聚合,从而为每组连续日期构建一行。

顺便说一句,最好避免使用保留字作为列名。

答案 1 :(得分:0)

所以基本上我认为正确的答案是@mathguy评论。 在这里,我只是在扩展并提供正确的完整查询。

select GROUP_NAME, grp_id, min(date_field) as starting_date, max(date_field) as ending_date
from (
select DATE_FIELD, GROUP_NAME, 
row_number() over ( order by date_field) - row_number() over ( partition by group_name order by date_field ) as grp_id
from darber.my_table) innested
group by GROUP_NAME, grp_id
order by min(date_field);

请注意:我更改了字段名称,因为它们在我的数据库上发生了冲突。在此解决方案中,DATE现在为DATE_FIELD,GROUP现在为GROUP_NAME。

我发现这是一个非常聪明和优雅的解决方案。 我希望能帮助别人。

答案 2 :(得分:0)

我在小组中的多个成员遇到相同的问题。如果遇到相同的问题,请将GROUP_NAME替换为“ groupMember1,groupMember2,...”