Объединение записей запроса с приоритетом NULL
Есть задача выбрать записи из таблицы(MSSQL) и сгруппировать их по ID и DT, а так же если у одной из записи с одинаковыми id и DT поле date_end is null, то выбрать эту запись, а если нет такого поля, то выбрать максимальную дату(вывод поля end_date обязателен)
Структура таблицы
ID | DT | date_end |
---|---|---|
12345 | Q2 | NULL |
12345 | Q2 | 01.01.2023 |
Пробовал такой запрос, но возвращаются обе записи
select ID,DT,case when date_end is NULL then null else MAX(date_end) end date_end from test
GROUP BY ID,DT,date_end
Помогает оконная функция FIRST_VALUE, но работает крайне медленно
select ID,DT,date_end from(
select ID,DT,FIRST_VALUE(date_end) OVER(ORDER BY date_end asc)date_end from test
)g
GROUP BY ID,DT,date_end
Какие ещё есть варианты?
p.s. Спасибо за ответ @Akina, итоговый запрос получился таким:
select ID, DT, date_end from (
SELECT ID, DT, date_end,
ROW_NUMBER() OVER (PARTITION BY ID, DT ORDER BY date_end asc) rn
FROM test
)cte
WHERE rn = 1;
Данная конструкция работает на много быстрее чем с FIRST_VALUE
Ответы (2 шт):
Скорее всего, речь идёт о тривиальном
WITH cte AS (
SELECT ID, DT, date_end,
ROW_NUMBER() OVER (PARTITION BY ID, DT ORDER BY COALESCE(date_end, '9999-12-31') DESC) rn
FROM test
)
SELECT ID, DT, date_end
FROM cte
WHERE rn = 1;
Ещё один вариант без CTE. Заменяем NULL на максимально возможную дату, берём максимум, и если он получился это максимальной датой, то заменяем обратно на NULL.
SELECT ID, DT, NULLIF(COALESCE(date_end, '9999-12-31'), '9999-12-31') AS date_end
FROM test
GROUP BY ID, DT