当前位置: 首页 > 知识库问答 >
问题:

SQL查询将不连续时间序列制作为连续时间序列

益麻雀
2023-03-14

我试图在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
----------

这样做的逻辑是start date1和end date1将是连续的。另外start_date2和end date2需要是连续的。如果在某些时候end date2与下一个start date2不匹配,那么需要添加一个具有相同id并且具有enddate2作为下一个start date1的新行。

非常感谢您的帮助。

共有2个答案

谢璞
2023-03-14

我在Microsoft SQL server上也做了类似的事情。这就是我所用的:

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

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

通煜祺
2023-03-14

例如,我进行下一个查询

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;
 类似资料:
  • 我正在处理一个大的时间序列,其中一列包含四个不同的传感器,一列包含测量值。我需要为属于同一时间的测量分配一个 id。问题是,每个设备的测量时间略有不同,因此我不能简单地按时间戳对它们进行分组。在按时间排序的数据框中,应分组的测量值可以通过唯一设备 ID 序列进行识别。这里的问题是,一次 4 台设备记录一个值,另一次 3 台设备记录一个值。我的数据如下所示。 您可以通过以下方式复制: 我需要为连续的

  • 我需要实施一个连续的任务时间表, 我通过Quartz通过,接下来的三次执行 但我希望02:45:00之后的下一次行刑是在03:30:00而不是03:00:00 有什么办法能做到吗

  • 问题内容: 如果我有串,我要检查,如果它作为一个连续存在 串 中,我可以使用: 在非连续子 序列 的情况下,我可以使用什么?例: 问题答案: 我不知道是否有内置功能,但是手动操作相当简单

  • 我有一个时间序列数据,我试图在其中找到在特定时间间隔内按顺序排列的连续记录,按每个连续记录系列分组。例如,如果每个集合(组)的记录之间的时间间隔为5分钟,则任何在5分钟内的记录下一条记录都将在集合中,任何超过5分钟的记录都将结束集合(组)。一个新的集合(组)将在5分钟内从接下来的两个记录中出现。 **分钟分隔不在表中,在查询中计算 我可以按顺序找到2行之间的差异并提取它们,但我不确定如何提取一系列

  • 给定一个有N个元素的数组A,我想在A的所有可能的连续子序列中找到最小元素的总和。我知道如果N很小,我们可以寻找所有可能的子序列,但是当N高达10^5时,找到这个总和的最佳方法是什么? 示例:设 N=3 且 A[1,2,3] 则 ans 为 10,作为可能的连续子序列 {(1),(2),(3),(1,2),(1,2,3),(2,3)} 因此最小元素之和 = 1 2 3 1 1 2 = 10

  • 我有ISO8601格式的持续时间值,我将其转换为时间值为整数秒,如下所示: ISO8601格式的持续时间值=“P1Y”。 我将该值存储在“时间-单位-秒”中。因此,当我检索的值将是在int,我想转换回ISO8601持续时间格式,所以我应该得到“P1Y”转换后回来。 有没有快速的方法可以做到这一点?或者我必须把时间的int值转换成float,然后通过某种方法把它转换成ISO8601持续时间。