SQL Server Return rows based on the max value of a column

yhxst69z  于 2023-03-17  发布在  其他
关注(0)|答案(2)|浏览(159)

I have a table of results like this, where the usage of each item totals 100%:
| Item | Usage | Customer |
| ------------ | ------------ | ------------ |
| Item1 | 90 | Customer 1 |
| Item1 | 10 | Customer 2 |
| Item2 | 54 | Customer 3 |
| Item2 | 46 | Customer 2 |
| Item3 | 23 | Customer 4 |
| Item3 | 77 | Customer 5 |

From this, I want to only show the rows with the max usage of each item, to show the customer that used the most of the item, so my results would be:

ItemUsageCustomer
Item190Customer 1
Item254Customer 3
Item377Customer 5

I've tried using max and group by, but I can't seem to get it to return only the max usage rows, I always end up with all 6 rows due to the need to include the customer column. Is there anyway to achieve this?

piok6c0g

piok6c0g1#

You can allow the ROW_NUMBER window function to craft a ranking value for each of your items, ordered by usage. Then make TOP(1) WITH TIES filter values with respect to the ORDER BY clause, getting only the first value tied (row number = 1, or if you will, the greatest usage value for each item).

SELECT TOP(1) WITH TIES *
FROM tab 
ORDER BY ROW_NUMBER() OVER(PARTITION BY [Item] ORDER BY [Usage] DESC)

Equivalently, you can compute the ROW_NUMBER window function first, then select all rows that have ranking = 1 in a subquery.

WITH cte AS (
    SELECT *, 
           ROW_NUMBER() OVER(PARTITION BY [Item] ORDER BY [Usage] DESC) AS rn
    FROM tab 
)
SELECT [Item], [Usage], [Customer]
FROM cte 
WHERE rn = 1

Output:

ItemUsageCustomer
Item190Customer 1
Item254Customer 3
Item377Customer 5

Check the demo here .

Consider learning more about these SQL-Server tools at the corresponding linked web pages.

mf98qq94

mf98qq942#

I have used data provided by you to create a SQLFIDDLE.
I want to only show the rows with the max usage of each item, to show the customer that used the most of the item.

This can be achieved as

select t1.item, t1.usage, t1.customer
from table1 t1
inner join (
  select item, MAX(usage) as maximum_usage
  from table1
  group by item
) t2 on t1.usage = t2.maximum_usage;

This gives me the expected output as :

itemusagecustomer
Item190Customer 1
Item254Customer 3
Item377Customer 5

You can see the demo in SQLFIDDLE

相关问题