2017-03-02 68 views
0

我有一個大表,我想按一個列值進行分組,併產生另一個列值的聚合。作爲一個聚合,我不關心實際值,只要它是按列分組的行中的任何中出現的值。類似於coalesce(),例如一個聚合產生它在輸入集中收到的第一個非空值。爲一個組返回任何值的聚合函數

當然,coalesce()不是一個聚合函數,居然沒有聚合函數匹配我需要的行爲,在文檔:

我能做些什麼來檢索查詢組中的每個組的任何元素? 我知道我可以使用min()max(),但我寧願避免將所有值相互比較以確定結果。一個解決方案可以防止爲已經具有值的組打印更多頁面,這將是理想的解決方案。這是一個很大的表格(磁盤上有幾GB)與大型組(數十萬行)。

我看過there are recursive CTE and lateral joins。我試圖總結我的頭圍繞這些,看看這些可以幫助...

下面是一個例子:

with t1(x) as (select * from generate_series(0, 10, 1)), 
    t2(x, y) as (select * from t1, t1 t2) 

select x 
    , any_element(y) -- how can I simulate this any_element() aggregate function? 
from t2 
group by x 
order by x 
+1

如果您不關心該值,那麼只需使用'min()'或'max()'。 –

+0

@a_horse_with_no_name這將是我的後備,但我特別感興趣的是不必比較組中的所有值來查找最小值或最大值。我查看了[第一/最後聚合](https://wiki.postgresql.org/wiki/First/last_(聚合)),但我不確定它們是如何工作的。他們啓用快捷方式嗎?快捷方式本質上是不可能的? – moooeeeep

+1

我不認爲'min()'的比較部分是什麼會減慢你的速度。這是掃描所有行並創建組。除非你有很多**行(每組數)(例如每組數百萬行),否則找到最小(或最大)將是整個步驟中最便宜的部分。 –

回答

2

distinct on將返回任何行:

with t1(x) as (select * from generate_series(0, 10, 1)), 
    t2(x, y) as (select * from t1, t1 t2) 

select distinct on (x) x,y 
from t2 
where y is not null 
order by x 

或者只是使用min/max正如評論中所建議的那樣。

+0

'獨特的'作品像一個魅力 - 非常感謝! – moooeeeep