Reputation: 55
I have to do a SQL statement to select for each day the min value from a column and when the value Order is the same the Max value from percentage.
Example:
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
The result that I want is something like:
Date Order Percentage
-------------------------------------------
01-03-2016 1 0
02-03-2016 1 0
03-03-2016 2 50
Upvotes: 1
Views: 78
Reputation: 220952
If you're using SQL Server 2012+, you could use the following solution:
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])
How does it work? For each partition (i.e. "group") we're selecting the first value, ordered by [Order]
. If two first values for [Order]
are the same, then order by [Percent]
descendingly. I.e. pretty much the requirement from your question.
Because the first value is the same for the entire partition, we can use DISTINCT
to remove duplicates, afterwards.
Be cautious with this solution, especially on SQL Server. A ROW_NUMBER()
based solution as suggested here will outperform mine, slightly on Oracle, and drastically on SQL Server (see comments)
Upvotes: 3
Reputation: 311508
You could use row_number
to sort the rows within each such group, and take the first one per group:
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
Upvotes: 4