Этого можно достичь с помощью аналитических функций MIN
и LAST_VALUE
.
SELECT c_number,
status,
LAST_VALUE(c_date) OVER(
PARTITION BY c_number,status ORDER BY c_date
ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
) AS latest_dt
FROM (
SELECT c_number,
CASE WHEN MIN (status) OVER( PARTITION BY c_number ) = 'A' THEN 'A'
ELSE status END --NVL(status,'I') or default for other than A & I
AS status,
c_date
FROM t1
) s
ORDER BY status,
latest_dt;
По сути, подзапрос проверяет, существует ли хотя бы одна буква «А» в группе, и полагается на фактэтот статус 'A' является наименее статусным по алфавиту.Если у вас есть другие статусы в нижнем регистре, вы можете изменить условие CASE
, добавив UPPER()
к статусу.
Функция LAST_VALUE
с предложением windowing получает самые последние даты для каждой комбинацииc_number и статус, полученный из подзапроса среди всех дат (UNBOUNDED PRECEDING AND UNB...
).
Вы не упомянули, что происходит, если в группе есть 2 других статуса, кроме «A», скажем «I»и 'E' или NULL
.В этом случае может потребоваться небольшая настройка, чтобы получить правильное значение для LAST_VALUE
.
Примечание : я использовал c_number
и c_date
для имен столбцов в качестве даты и номераявляются зарезервированными ключевыми словами и не должны использоваться для столбцов.
Демо