2017-04-25 208 views
1

我有分組PostgreSQL的OVER和GROUP

我有一個表(多了很多的東西在裏面,但不相關)的問題,看起來像:

id user 
0 1 
1 1 
2 1 
3 2 
4 2 
5 2 
6 1 
7 1 

我想得到以下值:

user start end 
1 0 2 
2 3 5 
1 6 7 

Basicaly,我需要用戶的第一次和最後一次發生,而不是亂序。 我知道我需要使用OVER(PARTITION BY ...),但我從來沒有用過它,不知道如何構建這個查詢。 如果我「按用戶分區」,它會忽略順序。如果我「通過ID分區,用戶」它再次返回錯誤。

的是我的嘗試(甚至沒有設法得到我所需要的,但爲表示我該怎麼辦呢,一旦我搞清楚「過度」部分的中點)

例子:

SELECT user, count(user) over (partition by user): 
user count 
1 5 
1 5 
1 5 
2 3 
2 3 
2 3 
1 5 
1 5 

SELECT user, count(user) over (partition by id, user): 
user count 
1 1 
1 1 
1 1 
2 1 
2 1 
2 1 
1 1 
1 1 
+0

'SELECT用戶分鐘(ID)在(用戶分區),MAX(ID)在(用戶分區)'?.. –

回答

4

使用的行數做法的不同與相同的用戶連續行分爲一組,並開始了一個新的組時,遇到新用戶。之後,使用group by來獲取每個組的開始和結束。

SELECT USER,MIN(ID) AS START,MAX(ID) AS END 
FROM (SELECT user,id, row_number() over(order by id) 
        - row_number() over (partition by user order by id) as grp 
     FROM tablename 
    ) T 
GROUP BY USER,GRP 
+0

這是一個經過測試的OP鏈接:http://rextester.com/AAN86440 – pozs

+0

完美。謝謝:) – darthzejdr

+0

@pozs ..感謝編輯和rextester鏈接。 –

3

到拿到啓動,ID的結束,請使用:

SELECT user, min(id) over (partition by user) "start", max(id) over (partition by user) "end" 
from table_name; 

更新 我的答案是基於錯誤的謂詞和錯。爲了提供正確的而不是重複@vkp一個,我做了這個可怕的構造:

create table so74 as 
select * from (values (0, 1), (1, 1), (2, 1), (3, 2), (4, 2), (5, 2), (6, 1), (7, 1)) t(id, u); 

with d as (
    with c as (
     with b as (
      select 
       * 
       , case when lag(u) over (order by id) <> u or id = min(id) over() then id end min 
       , case when lead(u) over (order by id) <> u or id=max(id) over() then id end max 
      from so74 
      ) 
     select u, min,max 
     from b 
     where coalesce(min,max) is not null 
    ) 
    select u,min,lead(max) over() max 
    from c 
) 
select * 
from d 
where coalesce(min,max) is not null 
; 

u | min | max 
---+-----+----- 
1 | 0 | 2 
2 | 3 | 5 
1 | 6 | 7 
(3 rows) 

Time: 0.456 ms 
+1

我得到的最小和最大總這一點。不是分區數據... – darthzejdr

+0

說實話,我不明白你的問題,我只是建立了一個查詢,會產生你想要的結果**我試圖得到以下值:**。如果我失敗,請更新問題 –

+0

問題是分區將返回每個用戶的最小值和最大值。 – darthzejdr