繁体   English   中英

sql查询将不连续的时间序列作为连续的时间序列

[英]sql query to make a discontinous time series as continous time series

我正在尝试在 Oracle 11g 中运行一个 sql 查询,它将把下面给定的数据集转换为下一个数据集。

id| start date1       | end date1          |   start date2      | end date2
-------------------------------------------------------------------------------------
1 | 27/02/2017 01:00:00| 27/02/2017 02:00:00| 27/02/2017 01:00:00|27/02/2017 02:00:00
-------------------------------------------------------------------------------------
2 | 27/02/2017 02:00:00| 27/02/2017 04:00:00| 27/02/2017 02:00:00|27/02/2017 03:00:00
-------------------------------------------------------------------------------------
2 | 27/02/2017 02:00:00| 27/02/2017 04:00:00| 27/02/2017 03:00:00|27/02/2017 03:30:00
-------------------------------------------------------------------------------------
 3 | 27/02/2017 04:00:00| 27/02/2017 05:00:00| 27/02/2017 04:00:00|27/02/2017 05:00:00
----------

Final dataset :

id | start date1       | end date1          | start date2        | end date2
-------------------------------------------------------------------------------------
1 | 27/02/2017 01:00:00| 27/02/2017 02:00:00| 27/02/2017 01:00:00|27/02/2017 02:00:00
-------------------------------------------------------------------------------------
2 | 27/02/2017 02:00:00| 27/02/2017 04:00:00| 27/02/2017 02:00:00|27/02/2017 03:00:00
-------------------------------------------------------------------------------------
2 | 27/02/2017 02:00:00| 27/02/2017 04:00:00| 27/02/2017 03:00:00|27/02/2017 03:30:00
-------------------------------------------------------------------------------------
2 | 27/02/2017 02:00:00| 27/02/2017 04:00:00| 27/02/2017 03:30:00|27/02/2017 04:00:00
-------------------------------------------------------------------------------------
 3 | 27/02/2017 04:00:00| 27/02/2017 05:00:00| 27/02/2017 04:00:00|27/02/2017 05:00:00
----------

这样做的逻辑是开始日期1 和结束日期1 将是连续的。 此外 start_date2 和 end date2 需要是连续的。 如果在某个时刻结束 date2 与下一个 startdate2 不匹配,则需要添加一个新行,该行具有与下一个开始 date1 相同的 id 和 enddate2。

任何帮助深表感谢。

例如我进行下一个查询

with s (id,start_date1,end_date1,start_date2,end_date2) as 
(select 
1, to_date('27/02/2017 01:00:00','dd/mm/yyyy HH24:MI:SS'), to_date('27/02/2017 02:00:00','dd/mm/yyyy HH24:MI:SS'), 
to_date('27/02/2017 01:00:00','dd/mm/yyyy HH24:MI:SS'), to_date('27/02/2017 02:00:00','dd/mm/yyyy HH24:MI:SS') from dual union all
select 2, to_date('27/02/2017 02:00:00','dd/mm/yyyy HH24:MI:SS'), to_date('27/02/2017 04:00:00','dd/mm/yyyy HH24:MI:SS'), 
to_date('27/02/2017 02:00:00','dd/mm/yyyy HH24:MI:SS'), to_date('27/02/2017 03:00:00','dd/mm/yyyy HH24:MI:SS') from dual union all
select 2, to_date('27/02/2017 02:00:00','dd/mm/yyyy HH24:MI:SS'), to_date('27/02/2017 04:00:00','dd/mm/yyyy HH24:MI:SS'), 
to_date('27/02/2017 03:00:00','dd/mm/yyyy HH24:MI:SS'), to_date('27/02/2017 03:30:00','dd/mm/yyyy HH24:MI:SS') from dual union all
select 3, to_date('27/02/2017 04:00:00','dd/mm/yyyy HH24:MI:SS'), to_date('27/02/2017 05:00:00','dd/mm/yyyy HH24:MI:SS'), 
to_date('27/02/2017 04:00:00','dd/mm/yyyy HH24:MI:SS'), to_date('27/02/2017 05:00:00','dd/mm/yyyy HH24:MI:SS') from dual
)
select distinct
id,sd1, ed1,  sd2, ed2 from (
select id,
       to_char(sd1,'dd/mm/yyyy HH24:MI:SS') sd1,
       to_char(ed1,'dd/mm/yyyy HH24:MI:SS') ed1, 
       to_char(border,'dd/mm/yyyy HH24:MI:SS') as sd2, 
       to_char(nvl(lead(border) over (partition by sd1, ed1 order by border),ed1),'dd/mm/yyyy HH24:MI:SS') as ed2  
from (
select id,
       start_date1 as sd1,
       end_date1 as ed1 ,
       decode(id1, 0,start_date2,end_date2)   as border,
       start_date2 as sd2 ,
       end_date2 as ed2,
       id1
       from s
       join (select rownum -1 as id1 from dual connect by level <= 2) on 1=1 )) 
where sd2 < ed2;

我对 Microsoft SQL 服务器做了类似的事情。 这就是我使用过的:

IF OBJECT_ID('tempdb..#Results') IS NOT NULL DROP TABLE #Results

CREATE TABLE #Results ( 
MonthYear DATE,
[Month] INT, 
[Year] INT                         
)

DECLARE @Y1 INT = 2019, @Y2 INT = 2020, @M1 INT = 1, @M2 INT = 12

WHILE @Y1 <= @Y2
BEGIN
        WHILE @M1 <= @M2
        BEGIN
            INSERT INTO #Results (MonthYear, [Month], [Year])
            VALUES(DATEFROMPARTS(@Y1,@M1,1),@M1,@Y1)
            SET @M1 = @M1+1
        END
        SET @Y1 = @Y1 + 1
END

SELECT R.MonthYear,
COUNT(T.CreatedOn) AS [Counts]
FROM #Results R
LEFT JOIN MyTable T ON DATEADD(MONTH, DATEDIFF(MONTH, 0, T.CreatedOn), 0) = R.MonthYear
GROUP BY MonthYear

所以,如果实际分组的数据是这样的:

在此处输入图片说明

转换后的系列(具有连续的月度数据,即填充所有缺失的月份)如下所示: 在此处输入图片说明

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM