SQL Server group by和max value for multiple column

时间:2016-09-14 22:32:37

标签: sql sql-server

我试图得到一行,其中两列中的一列具有每组的最大值,例如在下图中

Table Data

正如您所看到的,每个单元都有多个行,其中包含boxid,amnt1和amnt2。

我所追求的是,​​一旦查询运行,它将返回突出显示的行,这意味着它将返回单元ID,行的boxid为MAX(amnt1),MAX(amnt2)在行组中。因此,在单元10002的情况下,最大的amnt1是1.60,因此输出是

10002, 156, 1.60,

有人可以帮帮我吗?我无法完成这项工作

由于

2 个答案:

答案 0 :(得分:1)

如果您尝试比较amnt1和amnt2中的值,请参阅以下示例:

DECLARE @myTable TABLE (unit INT, boxid INT, amnt1 DECIMAL(8, 4), amnt2 DECIMAL(8, 4));
INSERT @myTable VALUES 
       (10002, 2, 0.042, 1.53), (10002, 27, 1.25, null), (10002, 158, null, null), (10002, 63, 1.75, null)
     , (10003, 156, 1.60, null), (10003, 2, 0.042, 1.53), (10003, 9, null, null), (10003, 19, 1.15, null)
     , (10004, 9, null, null), (10004, 62, 2.000, 100)
     , (10005, 69, 0.1, 6.9), (10005, 70, 0.2, 0.2), (10005, 71, 0.23, 0.69);

SELECT unit, boxid, amnt1, amnt2
FROM (
    SELECT unit, boxid, amnt1, amnt2, ROW_NUMBER() OVER (PARTITION BY unit ORDER BY Y DESC) R
    FROM @myTable
    CROSS APPLY (
        SELECT MAX(Y)
        FROM (VALUES (amnt1), (amnt2)) X(Y)) Z(Y)) T
WHERE R = 1;

此处交叉应用比较amnt1和amnt2并从这两个中获取最大值,然后,与其他答案类似,使用行号函数对结果集进行排序(按单位分区)。

答案 1 :(得分:1)

这是一种计算每列最大值的方法,然后使用该信息查找整个行:

select t.*
from (select t.*,
             max(amnt1) over (partition by unit) as max1,
             max(amnt2) over (partition by unit) as max2
      from t
     ) t
where (t.amnt1 = max1 and max1 >= max2) or
      (t.amnt2 = max2 and max2 >= max1);

这种方法的工作方式是计算每个unit的两列中每一列的最大值。这些最大值位于max1max2

然后where子句说:如果amnt1max1 相同,请保留此行,而 max1实际上是最大值。同样,如果amnt2max2 相同,则保留该行,而 max2实际上是最大值。

@ZLK给出的解决方案更为通用。如果你有更多的列,那么逻辑变得更复杂,以这种方式解释(呃,不是那么难,但apply看起来会更简单)。但对于两列,嵌套在apply之前的row_number()看起来有点复杂。