Sql-Server

我可以只計算連續記錄的 ROW_NUMBER() 嗎?

  • July 20, 2018

我需要計算連續值的序列號。這聽起來像是一份工作ROW_NUMBER()

DECLARE @Data TABLE
   (
   Sequence    TINYINT NOT NULL PRIMARY KEY,
   Subset  CHAR(1) NOT NULL
   )
INSERT INTO @Data (Sequence, Subset) VALUES
   (1, 'A'),
   (2, 'A'),
   (3, 'A'),
   (4, 'B'),  -- New subset
   (5, 'B'),
   (6, 'A')   -- New subset

SELECT
   Sequence, Subset,
   ROW_NUMBER() OVER (PARTITION BY Subset ORDER BY Sequence) AS SeqWithinGroup
FROM
   @Data

我希望該PARTITION子句在每次更改時重置計數Subset,但 SQL Server 會收集給定Subset值的所有值並對它們進行編號。這是我所期望的,也是我得到的:

Sequence Subset Expected Actual
-------- ------ -------- -----
1        A      1        1
2        A      2        2
3        A      3        3
4        B      1        1
5        B      2        2
6        A      *1*      *4*

當 SQL 到達第 6 行時,它繼續對子集“A”進行編號,而我將其視為恰好也被命名為“A”的新子集的第一行。

有沒有辦法ROW_NUMBER()嚴格地進行分區,而不是預設行為?

這里和其他地方有很多關於用 SQL 計算連續值的問題。但是,我還沒有看到解決PARTITION BY欄位中重複值的問題。大多數只處理增加的值,通常是日期。

我能夠使用以下方法解決這個問題LAG()

SELECT
   Sequence, Subset,
   CASE WHEN Sequence = 1 OR Subset <> LAG(Subset, 1) OVER (ORDER BY Sequence)
       THEN 'New subset'
       ELSE 'Continuation'
       END
FROM
   @Data

這將為記錄 #1、#4 和 #6 返回“新子集”。顯然LAG()分區與ROW_NUMBER().

顯然,這不提供行號,但它幫助我達到了辨識連續數字序列的目標,當子集標識符可以重複時。

我們在這裡所做的是,

  1. 計算重置(rst程式碼中的列)
  2. sum()獲取組(grp程式碼中的列)
  3. row_number()從分組中獲取。

程式碼,

SELECT row_number() OVER (PARTITION BY grp ORDER BY sequence) AS number,
 sequence,
 subset
FROM (
 SELECT count(rst) OVER (ORDER BY sequence) AS grp, *
 FROM (
   SELECT CASE WHEN subset != lag(subset) OVER (ORDER BY sequence) THEN 1 END AS rst, *
   FROM foo
 ) AS t1
) AS t2;

您可以在此處查看帶有結果的 DBFiddle

引用自:https://dba.stackexchange.com/questions/212713