计算SQL中连续分组项的数目
我想使用SQL(SQL server)在下面看到的“当前状态”字段中创建并填充以下条目数 有没有一种快速的方法可以使用类似于计算SQL中连续分组项的数目,sql,sql-server,tsql,window-functions,gaps-and-islands,Sql,Sql Server,Tsql,Window Functions,Gaps And Islands,我想使用SQL(SQL server)在下面看到的“当前状态”字段中创建并填充以下条目数 有没有一种快速的方法可以使用类似于row\u number()的东西来创建我要查找的字段?单靠这一点似乎是不够的 谢谢 如果序列是标识列,则可以执行以下操作: select t.*, row_number() over (partition by (Sequence - seq) order by Sequence) as [No. of Entries in Curr.Status] fr
row\u number()
的东西来创建我要查找的字段?单靠这一点似乎是不够的
谢谢 如果序列是标识列,则可以执行以下操作:
select t.*,
row_number() over (partition by (Sequence - seq) order by Sequence) as [No. of Entries in Curr.Status]
from (select t.*,
row_number() over (partition by [Curr.Status] order by Sequence) as seq
from table t
) t;
否则,您需要生成两个行编号
:
select t.*,
row_number() over (partition by (seq1- seq2) order by Sequence) as [No. of Entries in Curr.Status]
from (select t.*,
row_number() over (partition by id order by Sequence) as seq1
row_number() over (partition by id, [Curr.Status] order by Sequence) as seq2
from table t
) t;
这似乎是一个群体和岛屿问题。然而,关于如何实现这一点,有很多例子:
WITH VTE AS(
SELECT *
FROM (VALUES('9-9999-9',1 ,'Status D','Status A'),
('9-9999-9',2 ,'Status A','Status A'),
('9-9999-9',3 ,'Status A','Status A'),
('9-9999-9',4 ,'Status A','Status A'),
('9-9999-9',5 ,'Status A','Status B'),
('9-9999-9',6 ,'Status B','Status B'),
('9-9999-9',7 ,'Status B','Status B'),
('9-9999-9',8 ,'Status B','Status A'),
('9-9999-9',9 ,'Status A','Status A'),
('9-9999-9',10,'Status A','Status C'),
('9-9999-9',11,'Status C','Status C')) V(ID, Sequence, PrevStatus,CurrStatus)),
CTE AS(
SELECT ID,
[Sequence],
PrevStatus,
CurrStatus,
ROW_NUMBER() OVER (PARTITION BY ID ORDER BY [Sequence]) -
ROW_NUMBER() OVER (PARTITION BY ID,CurrStatus ORDER BY [Sequence]) AS Grp
FROM VTE V)
SELECT ID,
[Sequence],
PrevStatus,
CurrStatus,
ROW_NUMBER() OVER (PARTITION BY Grp ORDER BY [Sequence]) AS Entries
FROM CTE;
您可以使用
LAG
函数标记状态更改的行,并使用SUM()OVER()
为每个组分配唯一的编号。组内的编号很简单:
DECLARE @t TABLE (ID VARCHAR(100), Sequence INT, PrevStatus VARCHAR(100), CurrStatus VARCHAR(100));
INSERT INTO @t VALUES
('9-9999-9', 1, 'Status D', 'Status A'),
('9-9999-9', 2, 'Status A', 'Status A'),
('9-9999-9', 3, 'Status A', 'Status A'),
('9-9999-9', 4, 'Status A', 'Status A'),
('9-9999-9', 5, 'Status A', 'Status B'),
('9-9999-9', 6, 'Status B', 'Status B'),
('9-9999-9', 7, 'Status B', 'Status B'),
('9-9999-9', 8, 'Status B', 'Status A'),
('9-9999-9', 9, 'Status A', 'Status A'),
('9-9999-9', 10, 'Status A', 'Status C'),
('9-9999-9', 11, 'Status C', 'Status C');
WITH cte1 AS (
SELECT *, CASE WHEN LAG(CurrStatus) OVER(ORDER BY Sequence) = CurrStatus THEN 0 ELSE 1 END AS chg
FROM @t
), cte2 AS (
SELECT *, SUM(chg) OVER(ORDER BY Sequence) AS grp
FROM cte1
), cte3 AS (
SELECT *, ROW_NUMBER() OVER(PARTITION BY grp ORDER BY Sequence) AS SeqInGroup
FROM cte2
)
SELECT *
FROM cte3
ORDER BY Sequence
您的尝试是什么?请分享。这个数字是在什么领域计算的?谢谢。通过一些快速的改变,这解决了我的问题。知道“r1-r2分区”可以用于此类操作非常有帮助!
DECLARE @t TABLE (ID VARCHAR(100), Sequence INT, PrevStatus VARCHAR(100), CurrStatus VARCHAR(100));
INSERT INTO @t VALUES
('9-9999-9', 1, 'Status D', 'Status A'),
('9-9999-9', 2, 'Status A', 'Status A'),
('9-9999-9', 3, 'Status A', 'Status A'),
('9-9999-9', 4, 'Status A', 'Status A'),
('9-9999-9', 5, 'Status A', 'Status B'),
('9-9999-9', 6, 'Status B', 'Status B'),
('9-9999-9', 7, 'Status B', 'Status B'),
('9-9999-9', 8, 'Status B', 'Status A'),
('9-9999-9', 9, 'Status A', 'Status A'),
('9-9999-9', 10, 'Status A', 'Status C'),
('9-9999-9', 11, 'Status C', 'Status C');
WITH cte1 AS (
SELECT *, CASE WHEN LAG(CurrStatus) OVER(ORDER BY Sequence) = CurrStatus THEN 0 ELSE 1 END AS chg
FROM @t
), cte2 AS (
SELECT *, SUM(chg) OVER(ORDER BY Sequence) AS grp
FROM cte1
), cte3 AS (
SELECT *, ROW_NUMBER() OVER(PARTITION BY grp ORDER BY Sequence) AS SeqInGroup
FROM cte2
)
SELECT *
FROM cte3
ORDER BY Sequence