2017-06-21 101 views
0

給定一個表「點」,如:如何根據多列的排序對PostgreSQL中的聚合進行分組?

time | session_id | trail_id 
------------------------------ 
    1 |  1  | 1 
    2 |  1  | 1 
    3 |  1  | 3 
    4 |  1  | 3 
    5 |  1  | 3 
    6 |  1  | 1 
    7 |  1  | 1 
    8 |  1  | 1 
    9 |  1  | 1 
    10 |  1  | 1 

如何能夠將這些物品進行分組,這樣我可以使用「session_id的」聚合函數相對於trail_id,而按時間排序?即)我希望在trail_id隨時間變化時分組。

的查詢,如:

SELECT count(session_id), session_id, trail_id 
FROM <?> 

會產生:

count | session_id | trail_id 
------------------------------- 
    2 |  1  | 1 
    3 |  1  | 3 
    5 |  1  | 1 

我相信這可以用窗函數來完成,但並不成功爲止。

下並沒有完全得到我需要是的,因爲它組中的所有trail_ids不分時間:

SELECT session_id, trail_id, 
    first_value(time) OVER (PARTITION BY session_id, trail_id ORDER BY time) as v 
FROM points 

而且,在我的生產使用情況下,「點」表將是JOIN的結果,幷包含幾百萬行。這些點將具有PostGIS幾何類型,並與ST_MakeLine()函數進行彙總。性能明智,這將是更好的PL/pgSQL嘗試?

回答

3
with points(time , session_id , trail_id) as(
    select 1 ,  1  , 1 union all 
    select 2 ,  1  , 1 union all 
    select 3 ,  1  , 3 union all 
    select 4 ,  1  , 3 union all 
    select 5 ,  1  , 3 union all 
    select 6 ,  1  , 1 union all 
    select 7 ,  1  , 1 union all 
    select 8 ,  1  , 1 union all 
    select 11 ,  1  , 1 union all 
    select 12 ,  1  , 1 
) 

select count(*), session_id, trail_id 
from (
    select time, session_id, trail_id, 
    row_number() over(order by time) - 
    row_number() over(partition by session_id, trail_id order by time) as grp 
    from points 
)t 
group by grp, session_id, trail_id 
order by min(time) 

那麼,這應該給結果你所需要的,但如果

「點」表會的結果聯接和由幾百萬行

那麼可能的性能不會那麼理想。試試吧

+0

這很聰明!並且運作良好。不幸的是,這是一個概念證明,我幾個星期都無法真正測試,所以我不得不看看當時的表現如何。 –

相關問題