SQL Server - 获取前n行中的第1,第2和第3大值

时间:2016-05-10 15:04:31

标签: sql-server

对于(W,X,Y,Z)的每个组合,如何编写查询以获取最后N行中的第1,第2,第3大值

我想要这样的东西(在这种情况下N = 4):

| W_ID | X_ID | Y_ID | Z_ID |  Yr  | Mnth |  Amount |   Max1   |   Max2   |   Max3   |
|    5 |    5 |    7 |    6 | 2015 |    5 | 1000.00 |  1000.00 |   NULL   |   NULL   |
|    5 |    5 |    7 |    6 | 2015 |    6 | 5000.00 |  5000.00 |  1000.00 |   NULL   |
|    5 |    5 |    7 |    6 | 2015 |    7 | 4000.00 |  5000.00 |  4000.00 |  1000.00 |
|    5 |    5 |    7 |    6 | 2015 |    8 | 7000.00 |  7000.00 |  5000.00 |  4000.00 |
|    5 |    5 |    7 |    6 | 2015 |    9 | 9000.00 |  9000.00 |  7000.00 |  5000.00 |
|    5 |    5 |    7 |    6 | 2015 |   10 |  500.00 |  9000.00 |  7000.00 |  4000.00 |
|    5 |    5 |    7 |    6 | 2015 |   11 |  100.00 |  9000.00 |  7000.00 |   500.00 |
|    5 |    5 |    7 |    6 | 2015 |   12 |  500.00 |  9000.00 |   500.00 |   500.00 |
|    5 |    5 |    7 |    6 | 2016 |    1 | 2500.00 |  2500.00 |   500.00 |   500.00 |
|    5 |    5 |    7 |    6 | 2016 |    2 |  100.00 |  2500.00 |   500.00 |   100.00 |

提前感谢您提供的任何帮助

1 个答案:

答案 0 :(得分:0)

您可以使用以下查询:

SELECT [W_ID], [X_ID], [Y_ID], [Z_ID], [Yr], [Mnth], [Amount], 
       [1] AS Max1, [2] AS Max2, [3] AS Max3
FROM (
SELECT [W_ID], [X_ID], [Y_ID], [Z_ID], [Yr], [Mnth], [Amount], 
       s.v,
       ROW_NUMBER() OVER (PARTITION BY [W_ID], [X_ID], [Y_ID], [Z_ID], [Yr], [Mnth]
                          ORDER BY CASE WHEN s.v IS NULL THEN 1 ELSE 0 END, s.v DESC) AS rn 
FROM (
  SELECT [W_ID], [X_ID], [Y_ID], [Z_ID], [Yr], [Mnth], [Amount], 
         LAG([Amount]) OVER (PARTITION BY [W_ID], [X_ID], [Y_ID], [Z_ID]
                             ORDER BY [Yr], [Mnth]) AS prev1,
         LAG([Amount], 2) OVER (PARTITION BY [W_ID], [X_ID], [Y_ID], [Z_ID]
                                ORDER BY [Yr], [Mnth]) AS prev2,
         LAG([Amount], 3) OVER (PARTITION BY [W_ID], [X_ID], [Y_ID], [Z_ID]
                                ORDER BY [Yr], [Mnth]) AS prev3
  FROM mytable) AS t
CROSS APPLY (
     SELECT v
     FROM (VALUES([Amount]), (t.prev1), (t.prev2), (t.prev3)) AS x(v)) AS s(v) ) AS u
PIVOT (
   MAX(v) FOR rn IN ([1], [2], [3])) AS pvt
ORDER BY [Yr], [Mnth]

上述查询使用了SQL Server 2012提供的LAG窗口函数。

Demo here