获取SQL中每行的值的计数

时间:2015-01-30 02:52:39

标签: sql-server

我有一个SQL问题。以下是我的数据和查询

select ID from table

ID

4   
4   
5   
3   
5   
3   
3

我应该在我的选择列表中添加什么查询,以便它为每个特定行提供一个值的出现(我不想要总计数,我想要一些类似于出现的等级)。

4 1--this is the first time we got a 4 in the list, so 1
4 2--this is the second time we got a 4 in the list, so 2
5 1--this is the first time we got a 5 in the list, so 1
3 1--this is the first time we got a 3 in the list, so 1
5 2--this is the second time we got a 5 in the list, so 2
3 2--this is the second time we got a 3 in the list, so 2
3 3--this is the third time we got a 3 in the list, so 3

2 个答案:

答案 0 :(得分:1)

你想要ROW_NUMBER():

SELECT 
    [Id],
    ROW_NUMBER() OVER (PARTITION BY [Id] ORDER BY [Id])
FROM ...

您可能需要更改Order By子句以获得正确的输出。

答案 1 :(得分:1)

要从行的顺序生成编号,请使用row_number()rank()。问题是row_number() does not guarantee the original order will be preserved。你可以试试这个:

select
    [id],
    row_number() over (partition by id, order by (select 1)) as [rank]
from @t

但是,您会发现结果不符合原始顺序且有些令人困惑:

id  rank
3   1
3   2
3   3
4   1
4   2
5   1
5   2

要保留原始行顺序,可以使用identity列构建临时表或表变量。从那里选择row_number() id分区:

declare @t table ([tkey] int identity(1,1) primary key clustered, [id] int)
insert into @t (id) values (4), (4), (5), (3), (5), (3), (3)

select
    [id],
    row_number() over (partition by [Id] order by [tkey]) as [rank]
from @t
order by [tkey]

请注意,最终的order by [tkey]确实是必要的。该查询具有所需的结果:

id  rank
4   1
4   2
5   1
3   1
5   2
3   2
3   3

这是一种通用表格表达(CTE)方法。 CTE添加row_number()以按原始顺序维护行。 (这相当于前一个示例中的identity列。)当row_number()执行partition by id时,实际排名会带来第二个row_number()。这导致第1个4获得1,第2个4获得2等等。

第二个order by必须按原始顺序排序才能正确排名,但这仍然不足以保留输出中的顺序。最终declare @t table (id int) insert into @t (id) values (4), (4), (5), (3), (5), (3), (3) ;with [tRows] (rownum, id) as ( select row_number() over (order by (select 1)) as [rownum], [id] from @t ) select [id], row_number() over (partition by id order by [rownum]) as [rank] from [tRows] order by [rownum] 确保结束顺序相同。

id  rank
4   1
4   2
5   1
3   1
5   2
3   2
3   3

此查询也具有所需的结果:

rank()

在此示例中,您可以使用row_number()而不是第二个rank()this question中详细解释了这些函数之间的区别。如果不知何故,第一个row_number()生成了重复的行号,{{1}}将无法正常工作,但这不会发生。