您将如何基于一个列创建一个组标识符,但又按另一列进行排序?

时间:2019-05-06 20:06:40

标签: tsql

我正在尝试通过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 |
+-------+---------+------+

更新:我将其保留在最初的要求之外,但是一个帐户集群可以有两个以上的帐户。我更新了示例数据以包括这种情况。

1 个答案:

答案 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