1

我的數據是這樣的:如何GROUP BY不是唯一值以下行

table1 
_____________ 
id way time 
1 1 00:01 
2 1 00:02 
3 2 00:03 
4 2 00:04 
5 2 00:05 
6 3 00:06 
7 3 00:07 
8 1 00:08 
9 1 00:09 

我想知道在哪個時間段我是在哪一種方式:

desired output 
_________________ 
id way from to  
1 1 00:01 00:02 
3 2 00:03 00:05 
6 3 00:06 00:07 
8 1 00:08 00:09 

我試着使用一個窗口函數:

SELECT DISTINCT 
    first_value(id) OVER w AS id, 
    first_value(way) OVER w as way, 
    first_value(time) OVER w as from, 
    last_value(time) OVER w as to 
FROM table1 
WINDOW w AS (
    PARTITION BY way ORDER BY ID 
    range between unbounded preceding and unbounded following); 

我得到的是:

ID way from to  
1 1 00:01 00:09 
3 2 00:03 00:05 
6 3 00:06 00:07 

這是不正確的,因爲在路上我不是從00:01到00:09。 是否有可能按照順序執行分區,意味着只根據屬性進行分組,是否相等?

+1

'way'' 2'' 00:03 - 00:05'和'way'' 3'' 00:06-00:07'怎麼樣?這很混亂。 – JNevill

+0

這是錯的,我修好了。謝謝。 – telemachos

+0

你看起來像'id'和'time'都會嚴格按照平行升序。是這樣嗎?你確定?如果'id'是一個'serial'列,那很可能不是***總是這樣。這意味着一個時間片的最小「id」和最小「時間」可能在不同的行中。那麼結果應該是什麼? –

回答

2

如果你的情況很簡單,只要示例值表明,@Giorgos' answer很好地服務。

然而,這是通常不是這種情況。如果id列是serial,則不能假定以前的time的行也具有較小的id
此外,time值(或您可能有的timestamp)可以很容易地被複制,您需要使排序順序明確。

假設都可能發生,你想從每個時間片最早time該行的id(實際上是最小id的最早時間,可能有關係),這個查詢將處理正常情況:

SELECT * 
FROM (
    SELECT DISTINCT ON (way, grp) 
      id, way, time AS time_from 
     , max(time) OVER (PARTITION BY way, grp) AS time_to 
    FROM (
     SELECT * 
      , row_number() OVER (ORDER BY time, id) -- id as tie breaker 
      - row_number() OVER (PARTITION BY way ORDER BY time, id) AS grp 
     FROM table1 
    ) t 
    ORDER BY way, grp, time, id 
    ) sub 
ORDER BY time_from, id; 
  • ORDER BY time, id是毫不含糊的。假設時間是而不是唯一,請添加(假定唯一的)id以避免任意結果 - 這些查詢可能會以鬼鬼祟祟的方式發生變化。

  • max(time) OVER (PARTITION BY way, grp):沒有ORDER BY,窗口框架跨越PARTITION的所有行,所以我們得到每個時間片的絕對最大值。

  • 外部查詢層僅需要產生所需的排序順序中的結果,因爲我們通過使用DISTINCT ON綁定到在子查詢sub不同ORDER BY。詳細信息:

SQL Fiddle演示用例。

如果您希望優化性能,在這種情況下,plpgsql函數可能會更快。與此密切相關的答案:

旁白:不使用基本類型名稱time作爲標識符(也reserved word in standard SQL)。

2

我想你想是這樣的:

select min(id), way, 
     min(time), max(time) 
from (
select id, way, time, 
     ROW_NUMBER() OVER (ORDER BY id) - 
     ROW_NUMBER() OVER (PARTITION BY way ORDER BY time) AS grp 
from table1) t 
group by way, grp 

grp標識連續way值 '孤島'。在外部查詢利用該計算領域,我們可以得到開始年底分別使用MINway間隔MAX聚合函數倍。

Demo here

+0

@Nassim OP想要識別連續*'way'值的島嶼。在發佈的樣本數據中有** 4 **。請看*所需的輸出*和*不*在*我得到*輸出。 –

+0

是的,我誤解了這個問題,所以我刪除了我的答案,在這種情況下,您的答案更準確+1 – Nassim