选择 SQL Server 中排名第二的行

Posted

技术标签:

【中文标题】选择 SQL Server 中排名第二的行【英文标题】:Select rows with second minimum rank in SQL Server 【发布时间】:2014-12-23 22:15:39 【问题描述】:

我有一张包含客户编号、订单编号和排名字段的表格。每个客户编号可以有多个具有不同排名值的订单。例如。

cust#  order#  rank

1       12      1
1       13      3
1       14      2
2       15      2
2       16      1
3       17      3
3       18      4
3       19      1
3       20      2

我正在使用这个表来填充另一个看起来像这样的表。

cust   order1 order2 order3 order4
1       12      14     13
2       16      15
3       19      20     17    18

那么,如何选择第二、第三个最小排名来填充order2, order3, order4 字段?

编辑:我不想按排名 1、2、3 等进行,因为有时可能没有排名 2,因此 order2 字段将为空,但 order3 字段将被填充。我想以最低等级做。在 order1 中排名第一,在 order2 中排名第二,以此类推。

【问题讨论】:

在您编辑后,我更新了我的答案。希望对您有所帮助。 【参考方案1】:
SELECT R1.cust#, R1.order#, R2.order#, r3.order#, r4.order#
FROM MyTable AS R1
LEFT JOIN MyTable AS R2 ON R1.cust# = R2.cust# AND R2.rank = 2
LEFT JOIN MyTable AS R3 ON R1.cust# = R3.cust# AND R3.rank = 3
LEFT JOIN MyTable AS R4 ON R1.cust# = R4.cust# AND R4.rank = 4
WHERE R1.rank = 1

【讨论】:

【参考方案2】:

也许这会有所帮助:

SELECT cust#,
       MAX(CASE WHEN rank = 1 THEN order# END) AS order1,
       MAX(CASE WHEN rank = 2 THEN order# END) AS order2,
       MAX(CASE WHEN rank = 3 THEN order# END) AS order3,
       MAX(CASE WHEN rank = 4 THEN order# END) AS order4     
  FROM(SELECT cust#,
              order#,
              ROW_NUMBER() OVER (PARTITION BY cust# ORDER BY order#) rank
         FROM your_table
      )
 GROUP
    by cust#      

【讨论】:

【参考方案3】:

使用ROW_NUMBER()PIVOT 的组合,如下所示:

DECLARE @tmp TABLE (Customer INT, OrderNumber INT, Ranking INT)
INSERT INTO @tmp (Customer, OrderNumber, Ranking)
SELECT 1,       12,      1 UNION
SELECT 1,       13,      3 UNION
--SELECT 1,       14,      2 UNION
SELECT 2,       15,      2 UNION
SELECT 2,       16,      1 UNION
SELECT 3,       17,      3 UNION
SELECT 3,       18,      4 UNION
SELECT 3,       19,      1 UNION
SELECT 3,      20,      2


SELECT 
    Customer, 
    MAX(Order1) AS Order1, 
    MAX(Order2) AS Order2, 
    MAX(Order3) AS Order3, 
    MAX(Order4) AS Order4
FROM 
  (
    SELECT 
        *, 
        'Order' + CAST(ROW_NUMBER() OVER (PARTITION BY Customer ORDER BY Ranking) AS VARCHAR(4)) AS rn 
    FROM @tmp 
  ) d
PIVOT 
  (
    MAX(OrderNumber) FOR rn IN ([Order1], [Order2], [Order3], [Order4])
  ) p
GROUP BY Customer 

【讨论】:

我喜欢您对 Rank 字段本身进行 Rank 的想法。这是一个绝招。 很高兴为您提供帮助!如果这解决了您的问题,请通过单击复选标记考虑accepting it。这向更广泛的社区表明您已经找到了解决方案,并为回答者和您自己提供了一些声誉。没有义务这样做。

以上是关于选择 SQL Server 中排名第二的行的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server - 如何将 RANK 函数插入到已按排名顺序排序的行中?

SQL 查询获取主选择查询上的行排名或位置

使用 SQL Server Rank 函数对行进行排名而不跳过排名号

如何使用Excel函数求出某一列数的数值大小排名第二的那个数,

sql不用order by查找第二的思路

在 SQL Server 中使用 Dense_Rank 对具有排名的列进行排名组合