简体   繁体   中英

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.

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. So in the case of unit 10002 largest amnt1 is 1.60 therefore output is

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:

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

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 . These maxima are in max1 and max2 .

The where clause then says: Keep this row if amnt1 is the same as max1 and max1 is really the maximum. Similarly, keep the row if amnt2 is the same as max2 and max2 is really the maximum.

The solution given by @ZLK is more general. 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). But for two columns, the apply nested before the row_number() starts to look a bit complicated.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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