如何在SQL查询中添加组的序列号(如果同一组再次出现,则为新编号)

时间:2016-08-04 07:16:39

标签: sql sql-server tsql group-by grouping

我有一个与How to add sequence number for groups in a SQL query without temp tables

非常相似的问题

要从那里获取样本,我有一个由该表的前两列组成的数据结构,我想在查询中生成第三列:

Record  Group     GroupSequence
-------|---------|--------------
1       Chickens  1
2       Chickens  1
3       Horses    2
4       Cows      3
5       Horses    4
6       Horses    4

引用查询的不同之处在于,如果前一行在第二列中没有相同的值,则需要一个新数字。

我尝试添加一个行号并使用LAG()来检查前一行是否具有相同的值 - 如果是这样,请获取此生成列的先前值,如果不是,请取行号 - 但是看起来您无法重复使用您正在构建的列。

价值只需要是一个不同的数字 - 如果它按顺序排列并不重要。这也没关系:

Record  Group     GroupSequence
-------|---------|--------------
1       Chickens  1
2       Chickens  1
3       Horses    3
4       Cows      4
5       Horses    5
6       Horses    5

1 个答案:

答案 0 :(得分:2)

我认为这就是你所需要的:

WITH Src AS
(
    SELECT * FROM (VALUES 
    (1, 'Chickens'),
    (2, 'Chickens'),
    (3, 'Horses  '),
    (4, 'Cows    '),
    (5, 'Horses  '),
    (6, 'Horses  '))T(Record, [Group])
), Differentiator AS
(
    SELECT *,
    ROW_NUMBER() OVER (ORDER BY Record) -
        RANK() OVER (PARTITION BY [Group] ORDER BY Record) Diff
    FROM Src
)
SELECT Record, [Group], DENSE_RANK() OVER (ORDER BY [Group],Diff) NewGroup
FROM Differentiator
ORDER BY Record

它产生下表:

Record   Group      NewGroup
------   -----      --------
1        Chickens   1
2        Chickens   1
3        Horses     3
4        Cows       2
5        Horses     4
6        Horses     4

简短说明:

关键是计算整个表格和每个“[组]”组中记录的相对位置。如果记录相邻,则全局编号增加1,本地编号增加1.因此,ROW_NUMBER() - RANK()对于所有记录都相同。如果存在差距,则全局编号也会出现失真。它导致ROW_NUMBER() - RANK()在分离的组中生成不同的数字。