簡體   English   中英

根據連續日期計算排名(如果日期之間有間隔天數,則返回 1)

[英]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;

謝謝你。

對我來說,我發現按以下順序處理最容易:

  • 突出顯示上一行早於一天之前的所有情況
  • 對於間隔超過一天的每一行,output 為 1,而不是 0
  • 從那里,將所有前面的值相加,為每個間隙創建一個組 - 因為每個間隙都會有一個 1,每個新間隙將使累積和增加 1,但隨后的每個 0 不會,所以它將保留所有連續幾天在一個“島”
  • 最后,使用 partition by 將新的行號序列應用於每個組。

結果查詢是:

;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

您的示例數據具有所有相同的Name1Location1值,但是如果您需要在日期有間隔以及名稱或位置更改時重新開始排名,那么邏輯並沒有什么不同,您可以添加那些到所有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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM