SQL 只有一个日期列和重复条件的岛屿

SQL Island with just one date column and duplicated criteria

我是来寻求帮助的,我一直在尝试为记录数据集生成孤岛,但我做不到,我尝试过诸如滞后函数之类的东西,生成行每条记录,然后生成孤岛,但没有得到正确的结果。

我尝试过的解决方案参考:

我需要生成这个数据结构:

 | ChartShiftWeekdayDetailId | IslandStartsOn | IslandEndsOn | NoLinkingReason |
 |          3600             |   2021-06-25   |   2021-07-01 | 'Can't be .....'|
 |          3600             |   2021-07-02   |   2021-07-14 |       null      |
 |          3600             |   2021-07-15   |   2021-07-31 | 'Can't be .....'|
 |          3600             |   2021-08-01   |   2021-08-05 |       null      |

这是应该生成预期结果的记录示例。

我已经达到了这个结果

但是如您所见,这不是预期的结果。

这是我试过的:

SELECT *,
       CONCAT(NoLinkingReason,
              CAST(DATEDIFF(DAY,
                            LAG(DateValue, 1, CAST(ClearedData.DateValue AS datetime) - 1) OVER (PARTITION BY ChartShiftWeekdayDetailId,
                                                                                                              NoLinkingReason
                                                                                                 ORDER BY DateValue),
                            DateValue) AS varchar(10))) AS NumDays
FROM ClearedData;

非常感谢您的帮助。

假设您每天都有数据(如示例数据中所示),您可以从日期中减去枚举值并获得特定组的常量。对于每个链接原因,枚举都是分开的:

select ChartShiftWeekdayDetailId, NoLinkingReason,
       min(datevalue), max(datevalue)
from (select cd.*,
             row_number() over (partition by ChartShiftWeekdayDetailId, NoLinkingReason order by datevalue) as seqnum
      from ClearedData cd
     ) cd
group by datediff(day, -seqnum, datevalue)

在查看 link 和其他答案后,很明显差距没有被正确定义。这个答案使用了我编造的一些数据。你可以试试这样的

with 
gaps_cte as (
    select *, case when lag(NoLinkingReason, 1, NoLinkingReason) 
                            over (partition by ChartShiftWeekdayDetailId order by DateValue)<>NoLinkingReason then 1 
                   when lag(NoLinkingReason, 1, NoLinkingReason) 
                            over (partition by ChartShiftWeekdayDetailId order by DateValue) is null and NoLinkingReason is not null then 1
                   when lag(NoLinkingReason, 1, NoLinkingReason) 
                            over (partition by ChartShiftWeekdayDetailId order by DateValue) is not null and NoLinkingReason is null then 1
                   else 0 end gap
    from (values (3600, cast('2021-06-25' as date), 'Something'),
                 (3600, cast('2021-06-26' as date), 'Something'),
                 (3600, cast('2021-06-27' as date), 'Nothing'),
                 (3600, cast('2021-06-28' as date), 'Nothing'),
                 (3600, cast('2021-06-29' as date), null),
                 (3600, cast('2021-06-30' as date), Null),
                 (3600, cast('2021-07-01' as date), 'Something'),
                 (3600, cast('2021-07-02' as date), 'Something')
                  ) v(ChartShiftWeekdayDetailId, DateValue, NoLinkingReason)),
grps_cte as (
    select *, sum(gap) over (partition by ChartShiftWeekdayDetailId order by DateValue) grp
    from gaps_cte)
select ChartShiftWeekdayDetailId, 
       min(DateVAlue) IslandStartsOn,
       max(DateVAlue) IslandEndsOn,
       max(NoLinkingReason) NoLinkingReason
from grps_cte
group by ChartShiftWeekdayDetailId, grp
order by min(DateVAlue);
ChartShiftWeekdayDetailId   IslandStartsOn  IslandEndsOn    NoLinkingReason
3600                        2021-06-25      2021-06-26      Something
3600                        2021-06-27      2021-06-28      Nothing
3600                        2021-06-29      2021-06-30      NULL
3600                        2021-07-01      2021-07-02      Something