如果EndDateTime是第二天(午夜之后),Sql将条目分成两个条目。

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如果EndDateTime是第二天(午夜之后),Sql将条目分成两个条目。相关的知识,希望对你有一定的参考价值。

我有这个查询。

select 
    sth.Id,
    sth.CreatedDateTime, 
    EndDateTime = Lead(sth.CreatedDateTime, 1) over (partition by sth.Id order by sth.Id, sth.CreatedDateTime)
from 
    Sth as sth
order by 
    sth.Id, sth.CreatedDateTime

返回这些结果。

Id        StartDateTime                 EndDate                     
--------------------------------------------------------------------
2746743   2019-11-20 14:35:05.5841266   NULL                         
2746744   2019-11-20 14:35:05.5841266   NULL                         
3         2018-06-25 23:35:12.2799952   2018-06-26 09:57:27.8943163  
13        2018-06-26 09:57:27.8943163   2018-06-26 10:41:19.2973307  

我被要求更新上面的查询,把这行拆开来 Id=3 成两行。

意思是:如你所看到的记录与 Id 3 始于 23:35 and ends the **next day** at 09:57

我需要的是把这个记录分成两份。

第一条应该是来自 23:35 -> 23:59

而下面这个应该是来自 00:00 -> 09:57

如果记录跨度超过一天。什么都不需要做。 另外,最终的解决方案应该能够为一个 历史表. 300多万行.

所以记录的结果应该是这样的。

Id     StartDateTime                    EndDateTime
3      2018-06-25 23:35:12.2799952      2018-06-25 23:59:59.000000
3      2018-06-26 00:00:00.0000000      2018-06-26 09:57:27.8943163

我希望这有意义!

所有其他记录都会产生类似的结果。有一些记录是不需要拆分的,我有这样一个查询:select sth.Id, sth.CreatedDateTime, EndDateTime = Lead(sth.CreatedDateTime, 1)。

答案

你的问题中的结果集不可能是你所指定的查询的结果(每一个 id 会有 null 的值)。) 所以,我对这个问题的理解是,处理结束日期存在且在开始日期后一天的情况。

我只是使用横向连接。

with t as (
      select sth.*, CreatedDateTime as StartDateTime,
             Lead(sth.CreatedDateTime, 1) over (partition by sth.Id order by sth.Id, sth.CreatedDateTime) as EndDateTime
      from Sth as sth
     )
select t.id, v.*
from t cross apply
     (values (startdatetime,
               (case when datediff(day, startdatetime, enddatetime) = 1
                     then dateadd(second, -1, dateadd(day, 1, convert(datetime, convert(date, startdatetime))))
                     else enddatetime
                end)
              ),
              (dateadd(day, 1, convert(date, startdatetime)),
               (case when datediff(day, startdatetime, enddatetime) = 1
                     then enddatetime
                end)
              )
     ) v(startdatetime, enddatetime)
where v.enddatetime is not null;

这里 是一个db<>提琴。

以上是关于如果EndDateTime是第二天(午夜之后),Sql将条目分成两个条目。的主要内容,如果未能解决你的问题,请参考以下文章

绘制跨越午夜的到达和离开时间

查找时间跨越午夜边界的每组的第一天

如何在午夜 12:01 使用 Spring Boot 将间隔后的行添加到数据库 SQL 中

时间差 - 从午夜之前到午夜之后没有约会

用Python 创建一个工资结算程序,商量的报酬是第一天20元,第二天是第一天的2倍?

Oracle将行复制到具有不同日期的同一个表中