我正在尝试通过T-SQL创建列Group
。
如果一组帐户连续出现,则将其视为一组。如果该帐户在列表中再次出现在较低的位置(是否为群集),则将其视为一个新组。这似乎很简单,但我似乎看不到解决方案...下面是帐户3456的三个群集,每个群集具有不同的组号(组1,4和6)
+-------+---------+------+
| Group | Account | Sort |
+-------+---------+------+
| 1 | 3456 | 1 |
| 1 | 3456 | 2 |
| 2 | 9878 | 3 |
| 3 | 5679 | 4 |
| 4 | 3456 | 5 |
| 4 | 3456 | 6 |
| 4 | 3456 | 7 |
| 5 | 1295 | 8 |
| 6 | 3456 | 9 |
+-------+---------+------+
更新:我将其保留在最初的要求之外,但是一个帐户集群可以有两个以上的帐户。我更新了示例数据以包括这种情况。
答案 0 :(得分:1)
这就是我要做的:
--Sample Data
DECLARE @table TABLE (Account INT, Sort INT);
INSERT @table
VALUES (3456,1),(3456,2),(9878,3),(5679,4),(3456,5),(3456,6),(1295,7),(3456,8);
--Solution
SELECT [Group] = DENSE_RANK() OVER (ORDER BY grouper.groupID), grouper.Account, grouper.Sort
FROM
(
SELECT t.*, groupID = ROW_NUMBER() OVER (ORDER BY t.sort) +
CASE t.Account WHEN LEAD(t.Account,1) OVER (ORDER BY t.sort) THEN 1 ELSE 0 END
FROM @table AS t
) AS grouper;
结果:
Group Account Sort
------- ----------- -----------
1 3456 1
1 3456 2
2 9878 3
3 5679 4
4 3456 5
4 3456 6
5 1295 7
6 3456 8
根据以下操作说明进行更新(20190508)
我花了几天的时间来研究如何处理三个或三个以上的小组;这非常困难,但是我想出的方法可以处理更大的群集,并且比我的第一个答案要好得多。我更新了示例数据以包括更大的群集。
请注意,我为sort列包含UNIQUE约束-这将创建唯一索引。您不需要约束即可使用此解决方案,但在该列上具有索引(聚集,非聚集唯一或仅非聚集)将大大提高性能。
--Sample Data
DECLARE @table TABLE (Account INT, Sort INT UNIQUE);
INSERT @table
VALUES (3456,1),(3456,2),(9878,3),(5679,4),(3456,5),(3456,6),(1295,7),(1295,8),(1295,9),(1295,10),(3456,11);
-- Better solution
WITH Groups AS
(
SELECT t.*, Grouper =
CASE t.Account WHEN LAG(t.Account,1,t.Account) OVER (ORDER BY t.Sort) THEN 0 ELSE 1 END
FROM @table AS t
)
SELECT [Group] = SUM(sg.Grouper) OVER (ORDER BY sg.Sort)+1, sg.Account, sg.Sort
FROM Groups AS sg;
结果:
Group Account Sort
----------- ----------- -----------
1 3456 1
1 3456 2
2 9878 3
3 5679 4
4 3456 5
4 3456 6
5 1295 7
5 1295 8
5 1295 9
5 1295 10
6 3456 11