-- some data
CREATE table dayworked (
id SERIAL NOT NULL PRIMARY KEY
, user_id INTEGER NOT NULL
, arrived_at DATE NOT NULL
, UNIQUE (user_id, arrived_at)
);
INSERT INTO dayworked(user_id, arrived_at) VALUES
(1, '2014-02-03')
,(1, '2014-02-05')
,(1, '2014-02-06')
,(1, '2014-02-07')
--
,(2, '2014-02-03')
,(2, '2014-02-05')
,(2, '2014-02-06')
,(2, '2014-02-07')
,(2, '2014-02-08')
--
,(3, '2014-02-03')
,(3, '2014-02-04')
,(3, '2014-02-05')
,(3, '2014-02-07')
--
,(5, '2014-02-08')
;
-- The query
WITH RECURSIVE stretch AS (
SELECT dw.user_id AS user_id
, dw.arrived_at AS first_day
, dw.arrived_at AS last_day
, 1::INTEGER AS nday
FROM dayworked dw
WHERE NOT EXISTS (-- Find start of chain: no previous day
SELECT * FROM dayworked nx
WHERE nx.user_id = dw.user_id
AND nx. arrived_at = dw.arrived_at -1
)
UNION ALL
SELECT dw.user_id AS user_id
, st.first_day AS first_day
, dw.arrived_at AS last_day
, 1+st.nday AS nday
FROM dayworked dw -- connect to chain: previous day := day before this day
JOIN stretch st ON st.user_id = dw.user_id AND st.last_day = dw.arrived_at -1
)
SELECT * FROM stretch st
WHERE (st.nday > 1 OR st.first_day = NOW()::date) -- either more than one consecutive dat or starting today
AND NOT EXISTS (-- Only the most recent stretch
SELECT * FROM stretch nx
WHERE nx.user_id = st .user_id
AND nx.first_day > st.first_day
)
AND NOT EXISTS (-- omit partial chains
SELECT * FROM stretch nx
WHERE nx.user_id = st .user_id
AND nx.first_day = st.first_day
AND nx.last_day > st.last_day
)
;
结果:
CREATE TABLE
INSERT 0 14
user_id | first_day | last_day | nday
---------+------------+------------+------
1 | 2014-02-05 | 2014-02-07 | 3
2 | 2014-02-05 | 2014-02-08 | 4
(2 rows)
有趣的问题......你可以请加表格的架构? –
模式和样本数据(以'CREATE TABLE'和'INSERT's)和预期结果请。 –
请添加真实的DDL +样本数据。请不要使用简写符号。 – joop