SQL Server-查找特定日期内的所有记录(不是那么简单!)

时间:2017-02-01 12:03:09

标签: sql sql-server date

确定。我的SQL很漂亮,所以我很难解决这个问题。

我有一个表存储带有时间戳的记录。 我想要的是uids的列表,其中在1秒的时间范围内,该用户有2条或更多条记录。也许我已经让它变得更加复杂,只是想不出来。

缩短版本的表格(pk忽略)

    uid date
    1   2015-01-01 10:00:30.020*
    1   2015-01-01 10:00:30.300*
    1   2015-01-01 10:00:30.500*
    1   2015-01-01 10:00:39.000
    1   2015-01-01 10:00:35.000
    1   2015-01-01 10:00:37.800
    2   2015-02-02 12:00:30.000
    2   2015-02-02 14:00:30.000
    2   2015-02-02 15:00:30.000
    2   2015-02-02 18:00:30.000 
    3   2015-03-02 15:00:24.000 
    3   2015-03-02 15:00:20.000 *
    3   2015-03-02 15:00:20.300 *

我已经标记了*我希望匹配的记录旁边。 我喜欢的结果列表只是一个uid列表,所以我想要的结果就是 1 3

1 个答案:

答案 0 :(得分:1)

您可以使用exists

执行此操作
select distinct uid
from t
where exists (select 1
              from t t2
              where t2.uid = t.uid and
                    t2.date > t.date and
                    t2.date <= t.date + interval 1 second
             );

注意:添加1秒的语法因数据库而异。但上面给出了逻辑的想法。

在SQL Server中,语法为:

select distinct uid
from t
where exists (select 1
              from t t2
              where t2.uid = t.uid and
                    t2.date > t.date and
                    t2.date <= dateadd(second, 1, t.date)
             );

编辑:

或者,在SQL Server 2012+中,更快的替代方法是使用lead()lag()

select distinct uid
from (select t.*, lead(date) over (partition by uid order by date) as next_date
      from t
     ) t
where next_date < dateadd(second, 1, date);

如果你想要记录,而不仅仅是uid,那么你需要同时获得两者:

select t.*
from (select t.*,
             lag(date) over (partition by uid order by date) as prev_date,
             lead(date) over (partition by uid order by date) as next_date
      from t
     ) t
where next_date <= dateadd(second, 1, date) or
      prev_date >= dateadd(second, -1, date);