我有一個查詢,我認爲有一個相當常見的模式。考慮這張表:如何在執行分析查詢時避免DISTINCT作爲柺杖?
id | val | ts
---+-----+-------
a | 10 | 12:01
a | 12 | 12:05
a | 9 | 12:15
b | 30 | 12:03
我想通過每個id的時間戳獲取最新值。一些方法,你可以做到這一點:
-- 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我提出的所有3個查詢應該按時間戳選取最新值。所以如果你的行被添加到示例表中,它應該處理得很好。 如果對於相同的值存在2個相同的時間戳,則會導致聚合查詢出現問題。 – kimbo305
「柺杖」+1!獨特是最廣泛使用的kludge來消除重複,實際上查詢有問題。有合法的用途,但對我而言,每當我看到它時,它就是查詢中的紅旗。 – Bohemian