I have a table:
| Insert Date | Value1 | Value2 | Group |
| ------------ | ------------ | ------------ | ------------ |
| 2023-01-01 | 123 | 135 | a |
| 2023-02-01 | 234 | 246 | a |
| 2023-01-02 | 456 | 468 | b |
| 2023-02-02 | 345 | 357 | b |
I would like to find for each group when it had the highest value and then from these dates choose the oldest.
for the above data: group a
has the maximum in February, group b
has the maximum in January, so the final result I expect is 2023-01-02
.
currently I do it like this:
SELECT MIN([Insert Date])
FROM (
SELECT [Insert Date], [RowNo] = ROW_NUMBER() OVER(PARTITION BY [Group] ORDER BY [Value1] DESC, [Insert Date] DESC) FROM table WITH(NOLOCK)
UNION
SELECT [Insert Date], [RowNo] = ROW_NUMBER() OVER(PARTITION BY [Group] ORDER BY [Value2] DESC, [Insert Date] DESC) FROM table WITH(NOLOCK)
) AS src
WHERE [RowNo] = 1
But I don't think this is the best available way.
4条答案
按热度按时间hgqdbh6s1#
You could use cross apply: If we assume Insert date is unique per group... I'm not sure how you define "elegant" easy to read? performance?
DBFiddle Demo
Returning:
You'd have to compare explain plans to see which is optimal given your system setup.
pgccezyw2#
This is an other approach to do it using CTEs :
Demo here
hm2xizp93#
You can use a simple ORDER BY to solve it i think:
This first sorts by every group's largest value1 or value2, and then takes the earliest date of those values. If you have duplicate max valueXs, you can add a second tie breaker to the ROW_NUMBER call
k97glaaz4#
Looks like you could simply use
GREATEST
inside the row-number's ordering.On older versions you don't have
GREATEST
. You can instead dodb<>fiddle