Это похоже на итерацию задачи наибольшее-n-на-группу
Я не совсем уверен, какие ограничения вы хотите наложить
- Самая большая дата
- Самая последняя дата (но не в будущем)
- Ближайшая дата к сегодняшнему дню (прошлое или настоящее)
Вот пример таблицы и котораястрока, которую мы хотели бы получить, если запросить 6/3/2019 :
| Item | RequiredDate | Price |
|------|--------------|-------|
| A | 2019-05-29 | 10 |
| A | 2019-06-01 | 20 | <-- #2
| A | 2019-06-04 | 30 | <-- #3
| A | 2019-06-05 | 40 | <-- #1
| B | 2019-06-01 | 80 |
Но я собираюсь догадаться, что вы ищете # 2
Мы можем определить нашу строку / наибольшую дату, сгруппировав по item
и используя агрегированную операцию, такую как MAX
для каждой группы
SELECT o.Item, MAX(o.RequiredDate) AS MostRecentDt
FROM Orders o
WHERE o.RequiredDate <= GETDATE()
GROUP BY o.Item
, которая возвращает это:
| Item | MostRecentDt |
|------|--------------|
| A | 2019-05-29 |
| A | 2019-06-01 |
| B | 2019-06-01 |
Однако, как только мы сгруппируемся по этой записи, проблема заключается в том, чтобы вернуться к исходной таблице, чтобы получить полную строку / запись, чтобы выбрать любую другую информацию, не являющуюся частью исходного оператора GROUP BY
Используя ROW_NUMBER
, мы можем сортировать элементы в наборе и указывать их порядок (самый высокий ... самый низкий)
SELECT *, ROW_NUMBER() OVER(PARTITION BY Item ORDER BY RequiredDate DESC) rn
FROM Orders o
WHERE o.RequiredDate <= GETDATE()
| Item | RequiredDate | Price | rn |
|------|--------------|-------|----|
| A | 2019-05-29 | 10 | 1 |
| A | 2019-06-01 | 20 | 2 |
| B | 2019-06-01 | 80 | 1 |
Так как мы отсортировали DESC
, теперь мы просто хотим запросить эту группу, чтобы получить самые последние значения для группы (rn=1
)
WITH OrderedPastItems AS (
SELECT *, ROW_NUMBER() OVER(PARTITION BY Item ORDER BY RequiredDate DESC) rn
FROM Orders o
WHERE o.RequiredDate <= GETDATE()
)
SELECT *
FROM OrderedPastItems
WHERE rn = 1
Вот MCVEв скрипте SQL
Дополнительная литература :