我有一个需要根据日期时间拆分的表
输入表
ID| Start | End
--------------------------------------------
A | 2019-03-04 23:18:04| 2019-03-04 23:21:25
--------------------------------------------
A | 2019-03-04 23:45:05| 2019-03-05 00:15:14
--------------------------------------------
所需输出
ID| Start | End
--------------------------------------------
A | 2019-03-04 23:18:04| 2019-03-04 23:21:25
--------------------------------------------
A | 2019-03-04 23:45:05| 2019-03-04 23:59:59
--------------------------------------------
A | 2019-03-05 00:00:00| 2019-03-05 00:15:14
--------------------------------------------
Thanks!!
即使范围跨越超过一天,此功能也有效
WITH cte AS (
SELECT
id,
start_time,
end_time,
gs,
lag(gs) over (PARTITION BY id ORDER BY gs) -- 2
FROM
a
LEFT JOIN LATERAL
generate_series(start_time::date + 1, end_time::date, interval '1 day') gs --1
ON TRUE
)
SELECT -- 3
id,
COALESCE(lag, start_time) AS start_time,
gs - interval '1 second'
FROM
cte
WHERE gs IS NOT NULL
UNION
SELECT DISTINCT ON (id) -- 4
id,
CASE WHEN start_time::date = end_time::date THEN start_time ELSE end_time::date END, -- 5
end_time
FROM
cte
- 热膨胀系数:
generate_series
函数每天生成一行新的一天。因此,如果没有日期更改,则没有任何价值
- 热膨胀系数:lag()窗函数 https://www.postgresql.org/docs/current/tutorial-window.html允许将当前日期值移动到下一行(当前结束是下一个开始)
- 使用此数据集,您可以计算新的开始值和结束值。如果没有
gs
值:没有日期更改。此时忽略了这一点。对于所有日期更改的情况:如果没有lag
value,它是开始(所以它不能得到以前的值)。在这种情况下,正常的start_time
被占用,否则将是新的一天,占用日期休息时间。这end_time
是在当天的最后一秒拍摄的(interval - '1 second'
)
- 第二部分:由于日期中断,总是有一个额外的记录需要合并。最后一条记录是从头开始的
end_time
(所以投射到date
). The CASE
子句将此步骤与迄今为止已忽略的无日期更改的情况结合起来。因此,如果start_time
and end_time
是在同一日期,这里是原始的start_time
被采取。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)