为表中的每个组选择前N行

Har*_*rsh 13 sql ranking

我正面临一个非常普遍的问题,即"为表格中的每个组选择前N行".

考虑一个包含id, name, hair_colour, score列的表.

我想要一个结果集,这样,对于每种头发颜色,让我获得前三名得分手的名字.

为了解决这个问题,我在Rick Osborne的博客文章"sql-getting-top-n-rows-for-a -class-query"中得到了我所需要的.

当我的分数相等时,该解决方案无法按预期工作.

在上面的例子中,结果如下.

 id  name  hair  score  ranknum
---------------------------------
 12  Kit    Blonde  10  1
  9  Becca  Blonde  9  2
  8  Katie  Blonde  8  3
  3  Sarah  Brunette 10  1    
  4  Deborah Brunette 9  2 - ------- - - > if
  1  Kim  Brunette 8  3
Run Code Online (Sandbox Code Playgroud)

考虑一下这行4 Deborah Brunette 9 2.如果这也与Sarah相同(10),那么"褐发"型头发的排名将为2,2,3.

这是什么解决方案?

mar*_*c_s 17

如果您使用的是SQL Server 2005或更高版本,则可以使用排名函数和CTE来实现此目的:

;WITH HairColors AS
(SELECT id, name, hair, score, 
        ROW_NUMBER() OVER(PARTITION BY hair ORDER BY score DESC) as 'RowNum'
)
SELECT id, name, hair, score
FROM HairColors
WHERE RowNum <= 3
Run Code Online (Sandbox Code Playgroud)

此CTE将按hair列的值"分区"您的数据,然后每个分区按分数(降序)排序并获取行号; 每个分区的最高分为1,然后是2等.

因此,如果您想要每组的TOP 3,只选择CTE中具有RowNum3或更少(1,2,3)的那些行- >那么你去!