t-sql按类别分组并获得前n个值

DJP*_*JPB 4 t-sql

想象一下,我有这张桌子:

Month | Person | Value
----------------------
Jan   | P1     | 1
Jan   | P2     | 2
Jan   | P3     | 3
Feb   | P1     | 5
Feb   | P2     | 4
Feb   | P3     | 3
Feb   | P4     | 2
...
Run Code Online (Sandbox Code Playgroud)

我如何构建一个t-sql查询来获取前2个值的行,而第三个查询获得其他值的总和?

像这样的东西:

RESULT: 
Month | Person | Value
----------------------
Jan   | P3     | 3
Jan   | P2     | 2
Jan   | Others | 1 -(sum of the bottom value - in this case (Jan, P1, 1))
Feb   | P1     | 5
Feb   | P2     | 4
Feb   | Others | 5 -(sum of the bottom values - in this case (Feb, P3, 3) and (Feb, P4, 2))
Run Code Online (Sandbox Code Playgroud)

谢谢

Lie*_*ers 5

假设您使用的是SQL Server 2005或更高版本,使用CTE就可以了.

  • 将a附加ROW_NUMBER到每一行,从最高值开始,每个月重置一次.
  • SELECT 此查询中每月的前2行(rownumber <= 2)
  • UNION 剩下的行(rownumber> 2)

SQL语句

;WITH Months (Month, Person, Value) AS (
  SELECT 'Jan', 'P1', 1 UNION ALL
  SELECT 'Jan', 'P2', 2 UNION ALL
  SELECT 'Jan', 'P3', 3 UNION ALL
  SELECT 'Feb', 'P1', 5 UNION ALL
  SELECT 'Feb', 'P2', 4 UNION ALL
  SELECT 'Feb', 'P3', 3 UNION ALL
  SELECT 'Feb', 'P4', 2
),
q AS (
  SELECT  Month
          , Person
          , Value
          , RowNumber = ROW_NUMBER() OVER (PARTITION BY Month ORDER BY Value DESC)
  FROM    Months
)
SELECT  Month
        , Person
        , Value
FROM    (        
          SELECT  Month
                  , Person
                  , Value
                  , RowNumber
          FROM    q
          WHERE   RowNumber <= 2 
          UNION ALL
          SELECT  Month
                  , Person = 'Others'
                  , SUM(Value)
                  , MAX(RowNumber)
          FROM    q
          WHERE   RowNumber > 2        
          GROUP BY
                  Month 
        ) q                          
ORDER BY
        Month DESC
        , RowNumber
Run Code Online (Sandbox Code Playgroud)

Kudo去Andriy教我一些新技巧.