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
我是来寻求帮助的,我一直在尝试为记录数据集生成孤岛,但我做不到,我尝试过诸如滞后函数之类的东西,生成行每条记录,然后生成孤岛,但没有得到正确的结果。
我尝试过的解决方案参考:
我需要生成这个数据结构:
| 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