【问题标题】:SQL query to compare rows satisfying a time stamp condition用于比较满足时间戳条件的行的 SQL 查询
【发布时间】:2018-10-06 00:00:28
【问题描述】:

我有以下格式的数据。

Column1 Column2 Column3 时间戳
   10 20 30 2017-04-25 14:15:00.000
   12 30 40 2017-04-25 14:15:15.000
   55 54 89 2017-04-25 14:15:30.000
   66 78 11 2017-04-25 14:15:45.000
   12 30 40 2017-04-25 14:16:00.000
   55 54 89 2017-04-25 14:16:15.000
   66 78 11 2017-04-25 14:16:30.000

时间戳的格式是

yyyy-mm-dd hh:mm:ss

每 15 秒记录一次数据。因此,任何连续两行的时间戳之间的差异应该是 15 秒。我有兴趣查询时差为例如 20 秒的行和 时间戳分别在 2017-04-25 14:15:00 和 2017-04-25 14:15:30 之间。

我从以下代码开始,它需要很长时间才能完成查询。

SELECT
  *
FROM
  dbo.Temp2 AS t1
WHERE
  EXISTS
  (
    SELECT
      *
    FROM
      dbo.Temp2 AS t2
    WHERE
      t2.TimeStamp - t1.TimeStamp = 20      
  )
  ;

我使用的是 MS SQL Server 2017。

任何建议,想法都会非常有帮助。

提前谢谢你。

【问题讨论】:

  • 您的示例数据似乎不正确...时间戳重复(以 4 个块为单位),因此不会增加 15 秒...它会及时退回。分组是什么?
  • 我真诚地希望时间戳值不要真正使用那种格式。这意味着它们被存储为字符串,这是一个大错误。如果该列使用 DateTime 类型会更好。 DateTime 列使用人类不可读的二进制格式,但对于处理日期值很有效,并且与内置日期函数兼容。您可能会看到字符串格式的列,但这只是查询工具试图提供帮助。
  • @scsimon 我的错!这是一个错字:刚刚更新了它
  • @JoelCoehoorn 时间戳采用“日期时间”格式。所以我认为这不是问题。
  • 没问题@Agni,但样本数据中仍然没有> 15秒的差距。不过,我确实将这个差距放在了下面的示例数据中。干杯!

标签: sql sql-server timestamp


【解决方案1】:

超前/滞后分析函数在这里可能会有所帮助:

WITH cte AS (
    SELECT *,
        DATEDIFF(s, TimeStamp, LEAD(TimeStamp, 1) OVER (ORDER BY TimeStamp)) AS diff
    FROM Temp2
    WHERE TimeStamp BETWEEN '2017-04-25 14:15:00' AND '2017-04-25 14:30:00'
)

SELECT *
FROM cte
WHERE diff >= 20;

Demo

在上面的演示中,我必须稍微修改您的示例数据才能返回任何内容,因为您的时间戳范围实际上没有值,因此下一个前导值相隔 20 秒。

【讨论】:

  • 当然。我明白你的意思!一般来说,我会登录数千个时间戳。但是,我会根据我的数据集调整这个差异值。
  • 我只是想知道如何在使用 LINQ to SQL 查询的 c# 应用程序中做同样的事情。
  • @Agni 在这种情况下,您可能应该提出一个新问题。
【解决方案2】:

使用LEAD 和LAG。我还将您的示例数据更改为实际间隔超过 15 秒。这将返回 gap 发生的 both 行。在这种情况下,是下面评论的两个。

create table #MyTable (C1 int, C2 int, C3 int, TimeStamps datetime)
insert into #MyTable
values
(10,20,30,'2017-04-25 14:15:00.000'),
(12,30,40,'2017-04-25 14:15:15.000'),
(55,54,89,'2017-04-25 14:15:30.000'),
(66,78,11,'2017-04-25 14:15:45.000'), --this row will also be returned
(12,30,40,'2017-04-25 14:16:15.000'), --changed minutes here. This is the only row > 15 second difference than the previous, ordered by TimeStamps
(55,54,89,'2017-04-25 14:16:30.000'),
(66,78,11,'2017-04-25 14:16:45.000')

;with cte as(
select
    *
    ,KeepMe = case when datediff(second,TimeStamps,lead(TimeStamps) over(order by TimeStamps)) > 20  or datediff(second,TimeStamps,lag(TimeStamps) over(order by TimeStamps)) < -20 then 1 else 0 end
from 
    #MyTable)

select
    C1
    ,C2
    ,C3
    ,TimeStamps
from cte
where KeepMe = 1

drop table #MyTable

【讨论】:

  • 感谢您的回答!因为我只能接受一个答案。我赞成你对逻辑的回答。
猜你喜欢
  • 1970-01-01
  • 2014-10-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-19
  • 1970-01-01
  • 2019-03-05
  • 2014-12-27
相关资源
最近更新 更多