2

我想分組的表中的列的列值以及何時滿足其他條件。例如,下表:GROUP BY列和條款在postgres

活動:

id session_id flags  created_at ... 
-------------------------------------------- 
1 100   OTHER  ... 
2 101   OTHER  ... 
3 101   NEW_SESSION ... 
4 101   OTHER  ... 
5 101   NEW_SESSION ... 
6 100   OTHER  ... 
7 102   OTHER  ... 

我希望得到以下結果:

session_id events_count first_event_id last_event_id 
------------------------------------------------------- 
100-0  2   1    6 
101-0  1   2    2 
101-1  2   3    4 
101-2  1   5    5 
102-0  1   7    7 

的基本想法是,我想提取從事件會話。他們按session_id分組。每當我有國旗NEW_SESSION我也想要一個新的會議。

查詢是這樣的:

SELECT ? as session_id 
    , count(id) as events_count 
    , MIN(id) as first_event_id 
    , MAX(id) last_event_id 
GROUP BY session_id 
    -- , and whenever flags is NEW_SESSION 
ORDER BY id 

但我不知道如何通過條件正確表達該組。任何想法 ?

+0

101-0和101-1背後的邏輯是什麼? –

+0

@JakubKania'101'是原始會話ID,'0','1','2'是一個增量,因此我們可以「剪切」會話並且仍然具有唯一的會話ID。因爲會話101有兩個'NEW_SESSION'標記,所以我想把這個會話分成3個部分。 –

+0

我最終用CTE內的窗口函數實現了這一點。第一個帶有延遲的窗口,另一個帶有總和,另外一個是'PARTITION'ing on session_id –

回答

2

更新2

在我注意到,你希望他們獨特的意見。然後我們可以使用一個變量:

SET @inc := 0; 

(
    SELECT CONCAT(session_id, '-', !ABS(STRCMP(flags, 'NEW_SESSION'))) AS session_id 
    , COUNT(id) AS events_count 
    , MIN(id) AS first_event_id 
    , MAX(id) last_event_id 
    FROM events 
    WHERE flags != 'NEW_SESSION' 
    GROUP BY events.session_id, events.flags 
    ORDER BY events.id 
) UNION (
    SELECT CONCAT(session_id, '-', @inc := @inc + 1) AS session_id 
    , COUNT(id) AS events_count 
    , MIN(id) AS first_event_id 
    , MAX(id) last_event_id 
    FROM events 
    WHERE flags = 'NEW_SESSION' 
    GROUP by events.id 
    ORDER BY events.id 
); 

更新

下防止了NEW_SESSION行分組:據我瞭解

(
    SELECT CONCAT(session_id, '-', !ABS(STRCMP(flags, 'NEW_SESSION'))) AS session_id 
    , COUNT(id) AS events_count 
    , MIN(id) AS first_event_id 
    , MAX(id) last_event_id 
    FROM events 
    WHERE flags != 'NEW_SESSION' 
    GROUP BY events.session_id, events.flags 
    ORDER BY events.id 
) UNION (
    SELECT CONCAT(session_id, '-1') AS session_id 
    , COUNT(id) AS events_count 
    , MIN(id) AS first_event_id 
    , MAX(id) last_event_id 
    FROM events 
    WHERE flags = 'NEW_SESSION' 
    GROUP BY id 
    ORDER BY events.id 
); 

原來的答覆

,您正嘗試按會話標識將事件分組d 「是否是NEW_SESSION」標誌。如果是這樣,那麼我會表達如下:

SELECT CONCAT(session_id, '-', !ABS(STRCMP(flags, 'NEW_SESSION'))) AS session_id 
, COUNT(id) AS events_count 
, MIN(id) AS first_event_id 
, MAX(id) last_event_id 
FROM events 
GROUP BY events.session_id, events.flags 
ORDER BY events.id; 
+0

可能有許多不同的'NEW_SESSION'標誌,導致許多新的會話。我更新了我的問題以反映這一點。 –

+0

@pinouchon,我已經更新了我的答案 –