【问题标题】:SQL Cut Stretch Date into various stretchsSQL 将 Stretch Date 切割成不同的时间段
【发布时间】:2020-04-22 08:24:50
【问题描述】:

我在一张桌子上有很多日期,而在另一张桌子上有一些日期要删减。

有了这个,我需要得到另一张桌子,里面的所有伸展都被其他日期切割了。

我暂时有这个:

DECLARE @UTCSTARTDATE DATETIME='2020-01-20 00:00:00.00'
DECLARE @UTCENDDATE DATETIME='2020-01-20 04:00:00.00'

DECLARE @T1 TABLE
(
    StartTime DATETIME,
    EndTime DATETIME,
    table_id int
)

DECLARE @T2 TABLE
(
    CutTime DATETIME,
    table2_id int
)


INSERT INTO @T1 SELECT @UTCSTARTDATE,@UTCENDDATE,1

INSERT INTO @T2 SELECT myCut,myID FROM (VALUES('2020-01-20 01:00:00.00',1),('2020-01-20 02:30:00.00',1),('2020-01-20 03:00:00.00',2))t2(myCut,myID)


SELECT * FROM @T1

SELECT * FROM @T2 order by CutTime ASC



DECLARE @STRETCHHOURSTABLE TABLE
    (
        startDate               DATETIME,
        endDate                 DATETIME

    );

    ;WITH DATESPLITTER AS
    (
            SELECT 
                StartTime AS stretchStartDate, 
                (SELECT TOP(1) CutTime FROM @T2 where CutTime < EndTime AND table_id = table2_id order by CutTime ASC) AS stretchEndDate,
                EndTime AS RealEndTime,
                table_id AS RealID
            FROM @T1
        UNION ALL 
            SELECT 
                stretchEndDate,
                (SELECT TOP(1) CutTime FROM @T2 where CutTime > stretchEndDate AND CutTime < RealEndTime AND table2_id = RealID order by CutTime ASC) AS stretchEndDate,
                RealEndTime,
                RealID
            FROM DATESPLITTER
            WHERE stretchEndDate < @UTCENDDATE
    )
        INSERT INTO @STRETCHHOURSTABLE (startDate, endDate)
        SELECT 
            stretchStartDate,
            CASE    
                WHEN @UTCENDDATE < stretchEndDate THEN @UTCENDDATE
                ELSE stretchEndDate
            END 
        FROM DATESPLITTER

SELECT * FROM @STRETCHHOURSTABLE

【问题讨论】:

  • 那么您的问题到底是什么?你什么都不问我们。您对所提供的数据的预期结果是什么?为什么你没有工作?
  • 我的问题是我在那里写的东西不起作用,我需要在 img 上做同样事情的东西
  • “它不起作用”不是一个问题,而是一个声明。 “您对所提供数据的预期结果是什么?为什么您的结果不起作用?如果您不问,我们无法回答您的问题.
  • 你熟悉Accepting an answer吗?

标签: sql sql-server tsql date


【解决方案1】:

这好像基本上是lead()之后union all:

select dt, lead(dt) over (order by dt)
from ((select v.dt
       from @t1 t1 cross apply
            (values (t1.startTime), (t1.endTime)) v(dt)
      ) union all
      (select t2.cuttime
       from @t2 t2
      )
     ) t

Here 是一个 dbfiddle。

【讨论】:

    【解决方案2】:

    试试这个,我已经做出改变了:

    DECLARE @UTCSTARTDATE DATETIME='2020-01-20 00:00:00.00'
    DECLARE @UTCENDDATE DATETIME='2020-01-20 04:00:00.00'
    
    DECLARE @T1 TABLE( StartTime DATETIME, EndTime DATETIME, table_id int);
    DECLARE @T2 TABLE ( CutTime DATETIME, table2_id int);
    
    
    INSERT INTO @T1 SELECT @UTCSTARTDATE,@UTCENDDATE,1
    INSERT INTO @T2 VALUES('2020-01-20 01:00:00.00',1),('2020-01-20 02:30:00.00',1),('2020-01-20 03:00:00.00',2);
    
    SELECT * FROM @T1
    SELECT * FROM @T2 order by CutTime ASC;
    
    DECLARE @STRETCHHOURSTABLE TABLE (startDate DATETIME, endDate DATETIME);
    
    WITH DATESPLITTER AS
        (
                SELECT 
                    StartTime AS stretchStartDate,
                    (select cuttime from (SELECT row_number() over(partition by table2_id order by CutTime ASC) rn, CutTime FROM @T2 where CutTime < EndTime AND table_id = table2_id)a
                      where a.rn = 1) AS stretchEndDate,
                    EndTime AS RealEndTime,
                    table_id AS RealID
                FROM @T1
            UNION ALL 
                SELECT 
                    stretchEndDate,
                    ISNULL((select cuttime from (SELECT row_number() over(partition by table2_id order by CutTime ASC) rn, CutTime FROM @T2 where CutTime > stretchEndDate AND CutTime < RealEndTime AND table2_id = RealID)a
                      where a.rn = 1), RealEndTime) AS stretchEndDate,
                    RealEndTime,
                    RealID
                FROM DATESPLITTER
                WHERE stretchEndDate < @UTCENDDATE
        )
    
    INSERT INTO @STRETCHHOURSTABLE (startDate, endDate)
    SELECT  stretchStartDate,
            CASE
                WHEN @UTCENDDATE < stretchEndDate THEN @UTCENDDATE
                    ELSE stretchEndDate
                        END as sommm
    FROM DATESPLITTER
    
    SELECT * FROM @STRETCHHOURSTABLE
    

    【讨论】:

    • 请准确解释您更改/修复的内容,以明确更改的内容和原因。
    • 在 cte 中使用 row_number() 代替 TOP,并在 strechenddate 中使用 ISNULL 以避免在 enddate col 中出现 null。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-05-11
    • 1970-01-01
    • 2012-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多