[英]Calculate rank based on Consecutive Dates (Return to 1 if there is a gap days between dates)
我正在嘗試獲取此表的排名列。
鑰匙 | 日期1 | 名稱1 | 位置1 |
---|---|---|---|
20 | 2021-12-30 | 安 | 站點 A |
23 | 2021-12-31 | 安 | 站點 A |
26 | 2022-01-03 | 安 | 站點 A |
28 | 2022-01-04 | 安 | 站點 A |
29 | 2022-01-05 | 安 | 站點 A |
32 | 2022-01-06 | 安 | 站點 A |
62 | 2022-01-08 | 安 | 站點 A |
63 | 2022-01-10 | 安 | 站點 A |
64 | 2022-01-11 | 安 | 站點 A |
65 | 2022-01-12 | 安 | 站點 A |
66 | 2022-01-13 | 安 | 站點 A |
所需的 Output:
鑰匙 | 日期1 | 名稱1 | 位置1 | 排名1 |
---|---|---|---|---|
20 | 2021-12-30 | 安 | 站點 A | 1 |
23 | 2021-12-31 | 安 | 站點 A | 2 |
26 | 2022-01-03 | 安 | 站點 A | 1 |
28 | 2022-01-04 | 安 | 站點 A | 2 |
29 | 2022-01-05 | 安 | 站點 A | 3 |
32 | 2022-01-06 | 安 | 站點 A | 4 |
62 | 2022-01-08 | 安 | 站點 A | 1 |
63 | 2022-01-10 | 安 | 站點 A | 1 |
64 | 2022-01-11 | 安 | 站點 A | 2 |
65 | 2022-01-12 | 安 | 站點 A | 3 |
66 | 2022-01-13 | 安 | 站點 A | 4 |
我嘗試使用從另一個帖子中獲得的腳本,但仍然無法獲得我想要的 Rank Column output
select
t.Date1,
t.Name1,
t.Location1,
row_number() over (partition by Name1, Location1, grp order by KEY1) as Rank1
from
(
select
t.*,
sum(case when gap > 1 then 1 else 0 end) over (partition by Name1, Location1, order by KEY1) as grp
from
(select
t.*,
isnull(datediff(day, Date1, lag(Date1) over (partition by Name1, Location1, order by KEY1)), 1) as gap
from Table1 t
) t
) t;
謝謝你。
對我來說,我發現按以下順序處理最容易:
結果查詢是:
;WITH FindTheGaps AS
(
-- highlight all cases where previous row is more than a day earlier
SELECT *, gap = CASE WHEN Date1 >
DATEADD(DAY, 1, LAG(Date1,1) OVER
(ORDER BY Date1))
THEN 1 ELSE 0 END FROM dbo.Table1
),
MarkTheGaps AS
(
-- add up all the preceding values to create a group for each gap
SELECT *, grp = SUM(gap) OVER
(ORDER BY Date1
ROWS UNBOUNDED PRECEDING) FROM FindTheGaps
)
SELECT Key1, Date1, Name1, Location1,
Rank1 = ROW_NUMBER() OVER
(PARTITION BY grp ORDER BY Date1)
FROM MarkTheGaps ORDER BY Name1, Location1, Date1;
Output:
鍵1 | 日期1 | 名稱1 | 位置1 | 排名1 |
---|---|---|---|---|
20 | 2021-12-30 | 安 | 站點 A | 1 |
23 | 2021-12-31 | 安 | 站點 A | 2 |
26 | 2022-01-03 | 安 | 站點 A | 1 |
28 | 2022-01-04 | 安 | 站點 A | 2 |
29 | 2022-01-05 | 安 | 站點 A | 3 |
32 | 2022-01-06 | 安 | 站點 A | 4 |
62 | 2022-01-08 | 安 | 站點 A | 1 |
63 | 2022-01-10 | 安 | 站點 A | 1 |
64 | 2022-01-11 | 安 | 站點 A | 2 |
65 | 2022-01-12 | 安 | 站點 A | 3 |
66 | 2022-01-13 | 安 | 站點 A | 4 |
您的示例數據具有所有相同的Name1
和Location1
值,但是如果您需要在日期有間隔以及名稱或位置更改時重新開始排名,那么邏輯並沒有什么不同,您可以添加那些到所有OVER()
子句,例如:
;WITH FindTheGaps AS
(
-- highlight all cases where previous row is more than a day earlier
SELECT *, gap = CASE WHEN Date1 >
DATEADD(DAY, 1, LAG(Date1,1) OVER
(PARTITION BY Name1, Location1 ORDER BY Date1))
THEN 1 ELSE 0 END FROM dbo.Table1
),
MarkTheGaps AS
(
-- add up all the preceding values to create a group for each gap
SELECT *, grp = SUM(gap) OVER
(PARTITION BY Name1, Location1 ORDER BY Date1
ROWS UNBOUNDED PRECEDING) FROM FindTheGaps
)
SELECT Key1, Date1, Name1, Location1,
Rank1 = ROW_NUMBER() OVER
(PARTITION BY Name1, Location1, grp ORDER BY Date1)
FROM MarkTheGaps ORDER BY Name1, Location1, Date1;
有了這個源數據,它給出了相同的 output。
這是一個間隙和孤島問題,我們必須為每個連續的日期運行提出一個偽組。 考慮以下方法,它使用行號方法的差異:
WITH cte AS (
SELECT *, CASE WHEN DATEDIFF(day,
LAG(Date1) OVER (PARTITION BY Location1
ORDER BY Date1),
Date1) > 1
THEN 1 ELSE 0 END AS Marker
FROM yourTable
),
cte2 AS (
SELECT *, SUM(Marker) OVER (PARTITION BY Location1 ORDER BY Date1) AS grp
FROM cte
)
SELECT [Key], Date1, Name1, Location1,
ROW_NUMBER() OVER (PARTITION BY Location1, grp ORDER BY Date1) AS Rank1
FROM cte2
ORDER BY Location1, Date1;
上面的策略是每當我們檢測到前一個日期與當前日期不連續時,在名為grp
的列中生成一個值 1。 我們可以對列進行求和以生成偽組,然后可以將其與ROW_NUMBER
一起使用以生成您想要的排名值。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.