2016-05-17 24 views
0

我有folloving數據「組」僅鄰接數據

表T1:

╔════╦═════════╦══════════════════╗ 
║ id ║ name ║  dt  ║ 
╠════╬═════════╬══════════════════╣ 
║ 1 ║ name1 ║ 05/05/2016 10:00 ║ 
║ 2 ║ name2 ║ 07/05/2016 10:00 ║ 
║ 3 ║ name1 ║ 08/05/2016 10:00 ║ 
║ 4 ║ name1 ║ 09/05/2016 10:00 ║ 
╚════╩═════════╩══════════════════╝ 

,我想「基團它由順序」或標記具有相同名稱的

每一個「連續的」組

這樣類似的東西

╔════════╦════════════════════════════════╦══════════════════════════════╦════════╗ 
║ name ║ min dt       ║ max dt      ║ agg id ║ 
╠════════╬════════════════════════════════╬══════════════════════════════╬════════╣ 
║ name1 ║ 05/05/2016 10:00    ║ 05/05/2016 10:00    ║ {1} ║ 
║ name2 ║ 07/05/2016 10:00    ║ 07/05/2016 10:00    ║ {2} ║ 
║ name1 ║ 08/05/2016 10:00    ║ 09/05/2016 10:00    ║ {3,4} ║ 
╚════════╩════════════════════════════════╩══════════════════════════════╩════════╝ 

或類似的東西塔牛逼

╔═══════════╦════╦═════════╦══════════════════╗ 
║ group id ║ id ║ name ║  dt  ║ 
╠═══════════╬════╬═════════╬══════════════════╣ 
║   1 ║ 1 ║ name1 ║ 05/05/2016 10:00 ║ 
║   2 ║ 2 ║ name2 ║ 07/05/2016 10:00 ║ 
║   3 ║ 3 ║ name1 ║ 08/05/2016 10:00 ║ 
║   3 ║ 4 ║ name1 ║ 09/05/2016 10:00 ║ 
╚═══════════╩════╩═════════╩══════════════════╝ 

是它在某種程度上可能在Postgres的9.4呢?

THX米哈爾

+0

OK, '連續' 是我一直在尋找 –

回答

1

一種方法是使用lag(),看名稱已更改。然後做值的累計總和:

select t.*, 
     sum(case when name = prev_name then 0 else 1 end) over (order by dt) as grp 
from (select t.*, 
      lag(name) over (order by dt) as prev_name 
     from t1 t 
    ) t; 

爲了聚合得到的最小值和最大值,我更喜歡的行數做法上的不同:

select name, min(dt), max(dt) 
from (select t.*, 
      (row_number() over (order by dt) - 
       row_number() over (partition by name order by dt) 
      ) as grp 
     from t1 t 
    ) t 
group by grp, name; 

要明白髮生了什麼,這是最好的使用單獨的行號運行子查詢。根據我的經驗,當你看到序列和它們的區別時,你會有一個「aha」時刻。

+0

日Thnx很多 字一個認爲 **選擇T *, (ROW_NUMBER()OVER(由DT順序) - ROW_NUMBER()OVER(由DT名順序) )從T1牛逼GROUP_ID ** 分區正是我需要 是的,有一些「啊哈」的時刻天才是如何僅僅是 MK –

+1

可能不是這個問題的情況下,但要小心,如果你有重複的日期。因爲會造成一些奇怪的結果。正如我剛剛意識到試圖獲得「aha」時刻。 http://sqlfiddle.com/#!15/a896e7/1 –