简体   繁体   English

SQL Server分组依据和多列的最大值

[英]SQL Server group by and max value for multiple column

I am trying to get a row where one of the two columns have a max value for each group, for eg in the image below 我正在尝试获得一行,其中两列之一对每个组都有一个最大值,例如在下图中

表数据

as you can see each unit has multiple rows with boxid, amnt1 and amnt2. 如您所见,每个单元都有多个带有boxid,amnt1和amnt2的行。

What I am after is once the query runs, it returns the lines highlighted meaning it will return the unit id, with boxid of the row with MAX(amnt1),MAX(amnt2) among the groups rows. 我需要的是查询运行后,它将返回突出显示的行,这将返回单元ID,并在各组行之间返回具有MAX(amnt1),MAX(amnt2)的行的boxid。 So in the case of unit 10002 largest amnt1 is 1.60 therefore output is 因此,对于单元10002,最大amnt1为1.60,因此输出为

10002, 156, 1.60,

Can someone please help me out? 有人可以帮我吗? I am not able to get this done 我无法完成这项工作

Thanks 谢谢

In the event you're trying to compare the values in amnt1 and amnt2, here's an example of how you could do that: 如果您要比较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;

The cross apply here compares amnt1 and amnt2 and gets the max value from those two, then, similar to the other answer, you use a row number function to order the result set (partitioned by unit). 此处的叉号比较amnt1和amnt2并从这两个值中获取最大值,然后类似于其他答案,使用行号函数对结果集进行排序(按单位划分)。

Here is a method that calculates the maximum for each column and then uses that information to find the overall row: 这是一种计算每一列的最大值,然后使用该信息查找整个行的方法:

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);

The way this works is by computing the maximum for each of the two columns for each unit . 这种工作方式是通过计算每个unit的两列中的每一列的最大值。 These maxima are in max1 and max2 . 这些最大值在max1max2

The where clause then says: Keep this row if amnt1 is the same as max1 and max1 is really the maximum. where子句接着说:保留此行如果amnt1相同max1 max1是真正的最大值。 Similarly, keep the row if amnt2 is the same as max2 and max2 is really the maximum. 同样,保留该行如果amnt2是一样的max2 max2是真正的最大值。

The solution given by @ZLK is more general. @ZLK给出的解决方案更为通用。 If you had more columns then the logic gets more complicated to explain this way (eh, not really that hard, but apply would then look simpler). 如果您有更多的专栏,那么用这种方法进行解释的逻辑会变得更加复杂(嗯,实际上并不那么难,但是apply看起来会更简单)。 But for two columns, the apply nested before the row_number() starts to look a bit complicated. 但是对于两列,嵌套在row_number()之前的apply看起来有点复杂。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM