【问题标题】:Create two record across hour end with same information跨小时结束创建两条具有相同信息的记录
【发布时间】:2021-02-20 15:26:42
【问题描述】:

我想根据时间将单行拆分为多行。以下是示例数据。

Status  MachineId        StartDate                  EndDate
---------------------------------------------------------------------------
RUN      1               2018-08-20 07:27:00.000    2018-08-20 08:23:00.000
IDLE     1               2018-08-20 08:23:01.000    2018-08-20 08:38:00.000
RUN      1               2018-08-20 08:38:01.000    2018-08-20 09:20:00.000
STOP     1               2018-08-20 09:20:01.000    2018-08-20 11:11:00.000

预期输出如下:

Status  MachineId        StartDate                  EndDate
---------------------------------------------------------------------------
RUN      1               2018-08-20 07:27:00.000    2018-08-20 07:59:59.000
RUN      1               2018-08-20 08:00:00.000    2018-08-20 08:23:00.000
IDLE     1               2018-08-20 08:23:01.000    2018-08-20 08:38:00.000
RUN      1               2018-08-20 08:38:01.000    2018-08-20 08:59:59.000
RUN      1               2018-08-20 09:00:00.000    2018-08-20 09:20:00.000
STOP     1               2018-08-20 09:20:01.000    2018-08-20 09:59:59.000
STOP     1               2018-08-20 10:00:00.000    2018-08-20 10:59:59.000
STOP     1               2018-08-20 11:00:00.000    2018-08-20 11:11:00.000

考虑到开始和结束时间,该小时的最后一个“事件”也会在接下来的几个小时内复制,直到发生新的事件更改。

【问题讨论】:

  • 开始。您想达到什么目标?为什么您认为添加更多条目会更好地为您服务?
  • 为什么当前表的记录要根据时间变化拆分成3条或4条记录?你确定这是最好的策略吗?

标签: sql sql-server datetime recursive-query


【解决方案1】:

一个选项使用递归查询:

with cte as (
    select status, machineid, 
        startdate,
        dateadd(hour, 1, datetimefromparts(year(startdate), month(startdate), day(startdate), datepart(hour, startdate), 0, 0, 0)) as enddate,
        enddate as maxdate
    from mytable
    union all
    select status, machineid, enddate, dateadd(hour, 1, enddate), maxdate
    from cte
    where enddate < maxdate
)
select status, machineid, startdate, 
    case when enddate < maxdate then enddate else maxdate end as enddate
from cte
order by startdate

Demo on DB Fiddle

状态 |机器ID |开始日期 |结束日期 :----- | --------: | :------------------------ | :------------------------ 运行 | 1 | 2018-08-20 07:27:00.000 | 2018-08-20 08:00:00.000 运行 | 1 | 2018-08-20 08:00:00.000 | 2018-08-20 08:23:00.000 空闲 | 1 | 2018-08-20 08:23:01.000 | 2018-08-20 08:38:00.000 运行 | 1 | 2018-08-20 08:38:01.000 | 2018-08-20 09:00:00.000 运行 | 1 | 2018-08-20 09:00:00.000 | 2018-08-20 09:20:00.000 停止 | 1 | 2018-08-20 09:20:01.000 | 2018-08-20 10:00:00.000 停止 | 1 | 2018-08-20 10:00:00.000 | 2018-08-20 11:00:00.000 停止 | 1 | 2018-08-20 11:00:00.000 | 2018-08-20 11:11:00.000

这使用半开日期范围,而不是从上限减去 1 秒,因为这对我来说更有意义。如果这是您真正想要的,您可以轻松地调整查询以抵消上限。

【讨论】:

  • 谢谢,我试过了,但收到错误:“语句终止。在语句完成之前,最大递归100已用尽。”。
  • @Alberto:如果您有超过 100 小时的范围,那么您需要在查询的最后添加 option(maxrecursion 0)
猜你喜欢
  • 2012-03-03
  • 1970-01-01
  • 1970-01-01
  • 2022-10-05
  • 1970-01-01
  • 1970-01-01
  • 2019-06-30
  • 2023-03-16
  • 1970-01-01
相关资源
最近更新 更多