這個如何使用窗口函數和大量嵌套子查詢來創建'範圍聚集'的例子。我只是適應它由USER_ID分區和分組,它似乎你想要做什麼:
SELECT user_id, min(login_time) as login_time, max(logout_time) as logout_time
FROM (
SELECT user_id, login_time, logout_time,
max(new_start) OVER (PARTITION BY user_id ORDER BY login_time, logout_time) AS left_edge
FROM (
SELECT user_id, login_time, logout_time,
CASE
WHEN login_time <= max(lag_logout_time) OVER (
PARTITION BY user_id ORDER BY login_time, logout_time
) THEN NULL
ELSE login_time
END AS new_start
FROM (
SELECT
user_id,
login_time,
logout_time,
lag(logout_time) OVER (PARTITION BY user_id ORDER BY login_time, logout_time) AS lag_logout_time
FROM app_log
) AS s1
) AS s2
) AS s3
GROUP BY user_id, left_edge
ORDER BY user_id, min(login_time)
Results in:
user_id | login_time | logout_time
---------+---------------------+---------------------
1 | 2014-01-01 08:00:00 | 2014-01-01 10:49:00
1 | 2014-01-01 10:55:00 | 2014-01-01 11:00:00
2 | 2014-01-01 09:00:00 | 2014-01-01 11:49:00
2 | 2014-01-01 11:55:00 | 2014-01-01 12:00:00
(4 rows)
它的工作原理是首先檢測每一個新系列的開始(由USER_ID分區),然後延伸並由分組檢測範圍。我發現我必須非常仔細地閱讀這篇文章才能理解它!
該文章建議通過刪除最內層的子查詢和更改窗口範圍,可以使用Postgresql> = 9.0簡化它,但我無法使其工作。