У меня есть запрос, который, как мне кажется, имеет довольно распространенный шаблон. Рассмотрим эту таблицу:Как избежать DISTINCT в качестве костыля при выполнении аналитических запросов?
id | val | ts
---+-----+-------
a | 10 | 12:01
a | 12 | 12:05
a | 9 | 12:15
b | 30 | 12:03
Я хочу получить последнее значение по метке времени для каждого идентификатора. Некоторые способы, вы можете сделать это:
-- where in aggregate subquery
-- we avoid this because it's slow for our purposes
select
id, val
from t
where (id, ts) in
(select
id,
max(ts)
from t
group by id);
-- analytic ranking
select
id, val
from
(select
row_number() over (partition by id order by ts desc) as rank,
id,
val
from t) ranked
where rank = 1;
-- distincting analytic
-- distinct effectively dedupes the rows that end up with same values
select
distinct id, val
from
(select
id,
first_value(val) over (partition by id order by ts desc) as val
from t) ranked;
Аналитическая классификация запросов чувствует, как тот, для которого это было бы проще всего придумать эффективный план запроса. Но эстетически и технически, это довольно уродливо (особенно, когда таблица имеет более чем один столбец значений). В нескольких местах производства мы используем отчетливый аналитический запрос, когда тестирование показывает, что производительность эквивалентна.
Есть ли способ сделать что-то вроде rank = 1, не закончив таким уродливым запросом?
Какой результат вы ожидаете, если есть еще одна строка типа 'a, 10, 13: 45'? (поэтому есть записи, где комбинация id и val не уникальна). – Beryllium
@Beryllium все три запроса, которые я представляю, должны выбрать последнее значение по метке времени. Поэтому он должен отлично справляться с этим, если ваша строка была добавлена в таблицу образцов. Если для одного и того же значения есть 2 одинаковых временных метки, это может вызвать проблему с агрегированным запросом. – kimbo305
+1 для «костыля»! Distinct является наиболее широко используемым kludge для устранения дубликатов, когда на самом деле есть проблема с запросом. Есть законное использование, но для меня это красный флаг в вопросе, когда я его вижу. – Bohemian