从两个不同的列中选择最小值

时间:2016-03-23 18:55:02

标签: sql sql-server select top-n

我必须做一个SQL语句来为每一天选择一个列的最小值,以及当Order的值与百分比的最大值相同时。

示例:

Date           Order            Percentage           
-------------------------------------------
01-03-2016      1                   0 
01-03-2016      2                   20
02-03-2016      1                   0
02-03-2016      2                   20
03-03-2016      2                   50
03-03-2016      2                   20

我想要的结果是:

Date           Order            Percentage           
-------------------------------------------
01-03-2016      1                   0 
02-03-2016      1                   0
03-03-2016      2                   50

2 个答案:

答案 0 :(得分:4)

您可以使用row_number对每个此类组中的行进行排序,并为每个组取第一个:

SELECT [Date], [Order], [Percentage]
FROM   (SELECT [Date], [Order], [Percentage],
               ROW_NUMBER() OVER (PARTITION BY [Date]
                                  ORDER BY [Order] ASC, [Percentage] DESC) AS rk
        FROM   mytable) t
WHERE  rk = 1

答案 1 :(得分:3)

如果您使用的是SQL Server 2012+,则可以使用以下解决方案:

SELECT DISTINCT
  [Date],
  FIRST_VALUE ([Order])   OVER (PARTITION BY [Date] ORDER BY [Order] ASC, [Percent] DESC),
  FIRST_VALUE ([Percent]) OVER (PARTITION BY [Date] ORDER BY [Order] ASC, [Percent] DESC)
FROM (
  VALUES('2016-03-01', 1, 0),
        ('2016-03-01', 2, 20),
        ('2016-03-02', 1, 0),
        ('2016-03-02', 2, 20),
        ('2016-03-03', 2, 50),
        ('2016-03-03', 2, 20)
) AS t([Date], [Order], [Percent])

它是如何工作的?对于每个分区(即"组"),我们选择按[Order]排序的第一个值。如果[Order]的两个第一个值相同,则按[Percent]递减排序。即几乎是你问题的要求。

由于整个分区的第一个值相同,我们可以使用DISTINCT删除重复项。

关于绩效的说明:

请谨慎使用此解决方案,尤其是在SQL Server 上。基于ROW_NUMBER()的解决方案https://facebook.github.io/react/docs/advanced-performance.html将胜过我的,略微在Oracle上,并且在SQL Server上 (参见评论)