【问题标题】:SQL calculate time difference on certain conditionSQL在特定条件下计算时间差
【发布时间】:2020-07-03 15:28:09
【问题描述】:

我在 SQL 服务器中有一个表,其中的数据如下图所示。所以我需要计算列值大于或等于 3 的日期与下一列值 0 之间的时间差。所以在下面的示例中,“9:51”,值为 3,在“9: 54"。所以这里的总时差是3分钟。再次下一个时段是从“9:57”到“10:02”,所以这里的时间差是5分钟。下一个插槽来自“10:03”,但没有对应的行具有 0 值。所以这里的时差是 4 分钟(从“10:03”到“10:06”)。所以总时差是(3+5+4),12分钟。任何形式的帮助将不胜感激。提前致谢。

   DateTime    Value
3/10/2020 9:50  1
3/10/2020 9:51  3
3/10/2020 9:52  1
3/10/2020 9:53  2
3/10/2020 9:54  0
3/10/2020 9:55  0
3/10/2020 9:56  1
3/10/2020 9:57  3
3/10/2020 9:58  2
3/10/2020 9:59  3
3/10/2020 10:00 2
3/10/2020 10:01 2
3/10/2020 10:02 0
3/10/2020 10:03 3
3/10/2020 10:04 1
3/10/2020 10:05 1
3/10/2020 10:06 1

编辑 2:我也有一个雪花数据库,并使用我在上表中生成的以下查询。

   with aggregatedData as 
  (
       select count ( EVENT_ID) as total , time_slice(to_timestamp_ntz(EVENT_CREATED_AT), 1, 'MINUTE') as minutePeriod
            from events  
            group by minutePeriod

            union

            SELECT
            0 as total,
            DATEADD(MINUTE, SEQ4(), time_slice(to_timestamp_ntz(select min(EVENT_CREATED_AT) from events), 1, 'MINUTE')) AS minutePeriod
            FROM TABLE(GENERATOR(ROWCOUNT=>20000))
            WHERE minutePeriod <= time_slice(to_timestamp_ntz(select max(EVENT_CREATED_AT) from events), 1, 'MINUTE')
 )
 select minutePeriod
  ,sum(total) over (partition by null order by minutePeriod rows between 9 preceding and current row) totalValue
  from aggregatedData
  order by minutePeriod;

我期待低于输出

【问题讨论】:

  • 您可以将测试数据作为文本发布吗?谢谢。
  • 并发布您的最佳尝试。以及您的预期结果。
  • @DaleK 我已经使用多个 SQL 查询生成了这个表,但我只是卡在了计算的最后阶段。为了避免混淆,我没有添加这些细节。这里
  • 我们不需要所有的查询,只要足以证明问题,称为minimal reproducible example
  • 如何将“9:51”和“9:54”之间的时间差设为4分钟?

标签: sql sql-server datetime


【解决方案1】:

你可以试试这个。

SELECT T1.*, 
    CASE 
        WHEN T1.Value = 3 AND (X3.Value = 0 OR X3.Value IS NULL) 
        THEN DATEDIFF(MINUTE,T1.DateTime , ISNULL(X0.[DateTime],  (SELECT DATEADD(MINUTE,1, MAX([DateTime])) FROM SampleData) )) END
FROM SampleData T1 
    OUTER APPLY ( SELECT TOP 1 * FROM SampleData T2 WHERE T2.[DateTime] > T1.[DateTime] AND T2.Value = 0 ORDER BY T2.DateTime ASC) X0
    OUTER APPLY ( SELECT TOP 1 * FROM SampleData T2 WHERE T2.[DateTime] < T1.[DateTime] AND T2.Value IN (0, 3) ORDER BY T2.[DateTime] DESC) X3
ORDER BY T1.[DateTime]

结果:

DateTime                Value       
----------------------- ----------- -----------
2020-03-10 09:50:00.000 1           NULL
2020-03-10 09:51:00.000 3           3
2020-03-10 09:52:00.000 1           NULL
2020-03-10 09:53:00.000 2           NULL
2020-03-10 09:54:00.000 0           NULL
2020-03-10 09:55:00.000 0           NULL
2020-03-10 09:56:00.000 1           NULL
2020-03-10 09:57:00.000 3           5
2020-03-10 09:58:00.000 2           NULL
2020-03-10 09:59:00.000 3           NULL
2020-03-10 10:00:00.000 2           NULL
2020-03-10 10:01:00.000 2           NULL
2020-03-10 10:02:00.000 0           NULL
2020-03-10 10:03:00.000 3           4
2020-03-10 10:04:00.000 1           NULL
2020-03-10 10:05:00.000 1           NULL
2020-03-10 10:06:00.000 1           NULL

【讨论】:

    【解决方案2】:

    所以我需要计算列值大于或等于 3 的日期与下一列值为 0 的日期之间的时间差。

    如果我理解正确:

    select t.*,
           (case when value >= 3
                 then datediff(minute,
                               datetime,
                               min(case when value = 0 then datetime end) over (order by datetime desc)
                              )
            end) as diff_minutes
    from t;
    

    Here 是一个 dbfiddle。

    【讨论】:

    • 谢谢。对于某些情况,它可以工作,但如果您考虑第二个插槽,它从“09:57”开始,到“10:02”结束。中间“9:59”的值又是 3,所以在这种情况下,计算出错了。
    • @Dany 。 . .我不同意。这回答了您提出的问题。如果您有不同的问题,您应该提出一个新的问题,并提供适当的样本数据和所需的结果。
    • 对不起,如果我的问题对你来说不是很清楚......但是如果你看到解释,我说最终输出应该是 12 分钟......而你的答案是 11 分钟。
    猜你喜欢
    • 2017-05-21
    • 1970-01-01
    • 1970-01-01
    • 2017-07-01
    • 1970-01-01
    • 2020-03-26
    • 2019-06-10
    • 1970-01-01
    • 2022-11-02
    相关资源
    最近更新 更多