从日期中选择时段
Posted
技术标签:
【中文标题】从日期中选择时段【英文标题】:select periods from date 【发布时间】:2018-02-19 09:12:43 【问题描述】:我在从缺勤列表中选择一个接一个的缺勤并将它们分组到时段时遇到问题。
date_from (data_od) date_to(data_do)
--------------------------
18/08/01 - 18/08/15
18/08/16 - 18/08/20
18/08/21 - 18/08/31
18/09/01 - 18/09/08
18/05/01 - 18/05/31
18/06/01 - 18/06/30
18/03/01 - 18/03/18
18/02/14 - 18/02/28
上面是缺勤列表,其结果应该是一个表格:
date_from (data_od) date_to(data_do)
--------------------------
18/08/01 18/09/08
18/05/01 18/06/30
18/02/14 18/03/18
目前,我做了类似的事情,但我只研究了两个:(
SELECT u1.data_od,u2.data_do
FROM l_absencje u1 CROSS APPLY
(SELECT * FROM l_absencje labs
WHERE labs.prac_id=u1.prac_id AND
TRUNC(labs.data_od) = TRUNC(u1.data_do)+1
ORDER BY id DESC FETCH FIRST 1 ROWS ONLY
) u2 where u1.prac_id=1067 ;
然后给我:
18/08/01 18/08/20 bad
18/08/16 18/08/31 bad
18/08/21 18/09/08 bad
18/05/01 18/06/30 good
18/02/14 18/03/18 good
【问题讨论】:
有多种方法可以解决gaps-and-island问题; this looks like a similar scenario 但您可能会在该标签下找到更好的方法。 【参考方案1】:您可以结合使用LAG()
、LEAD()
和LAST_VALUE()
分析函数:
SQL Fiddle
Oracle 11g R2 架构设置:
CREATE TABLE absences ( date_from, date_to ) AS
SELECT DATE '2018-08-01', DATE '2018-08-15' FROM DUAL UNION ALL
SELECT DATE '2018-08-16', DATE '2018-08-20' FROM DUAL UNION ALL
SELECT DATE '2018-08-21', DATE '2018-08-31' FROM DUAL UNION ALL
SELECT DATE '2018-09-01', DATE '2018-09-08' FROM DUAL UNION ALL
SELECT DATE '2018-05-01', DATE '2018-05-31' FROM DUAL UNION ALL
SELECT DATE '2018-06-01', DATE '2018-06-30' FROM DUAL UNION ALL
SELECT DATE '2018-03-01', DATE '2018-03-18' FROM DUAL UNION ALL
SELECT DATE '2018-02-14', DATE '2018-02-28' FROM DUAL;
查询 1:
SELECT *
FROM (
SELECT CASE
WHEN date_to IS NOT NULL
THEN LAST_VALUE( date_from ) IGNORE NULLS
OVER( ORDER BY ROWNUM )
END AS date_from,
date_to
FROM (
SELECT CASE date_from
WHEN LAG( date_to ) OVER ( ORDER BY date_to )
+ INTERVAL '1' DAY
THEN NULL
ELSE date_from
END AS date_from,
CASE date_to
WHEN LEAD( date_from ) OVER ( ORDER BY date_from )
- INTERVAL '1' DAY
THEN NULL
ELSE date_to
END AS date_to
FROM absences
)
)
WHERE date_from IS NOT NULL
AND date_to IS NOT NULL
Results:
| DATE_FROM | DATE_TO |
|----------------------|----------------------|
| 2018-02-14T00:00:00Z | 2018-03-18T00:00:00Z |
| 2018-05-01T00:00:00Z | 2018-06-30T00:00:00Z |
| 2018-08-01T00:00:00Z | 2018-09-08T00:00:00Z |
【讨论】:
以上是关于从日期中选择时段的主要内容,如果未能解决你的问题,请参考以下文章
每个时段的 MySQL 查询小计,小时从当天下午 2 点到第二天下午 2 点
R语言ggplot2可视化:可视化所有日期不同时段任务的持续时间将持续时间绘制成一条线(起始时间到结束时间),y轴表示活动发生的日期,x轴表示以小时为单位的时间
R语言ggplot2可视化:可视化所有日期不同时段任务的持续时间将持续时间绘制成一条线(起始时间到结束时间),y轴表示活动发生的日期,x轴表示以小时为单位的时间适应时间段跨越多天的情况