查找在24小时内创建的记录(尤其是最近24小时)

时间:2016-07-29 13:16:20

标签: sql sql-server tsql

我正在使用SQLServer 2012,我有一个像这样的时间戳表:

Id           INT      NOT NULL,  --PK
IdUser       INT      NOT NULL   --FK from table USER
-- Some other fields
CreationDate DATETIME NOT NULL

此表记录了用户所做的某种动作 我试图在24小时内找到 IF 用户执行此类操作20次以上(即该表中有相同IdUser的20条记录)。

问题是我不是要在过去24小时内检索记录,而是 24小时内的记录(从第1个记录到今天)

这就是我写的:

SELECT IdUser 
FROM MyTable
WHERE IdUser = 1 
    AND CreationDate BETWEEN DATEADD(day, -1, GETDATE()) AND GETDATE() -- <= WRONG

WHERE条款不符合我的需要,因为我不知道如何翻译“在24小时内从用户id = 1中搜索20条记录,尤其是最后24条小时“在SQL

样品
假设我们的用户Id = 1做了154次此操作。所以我的表中有154条记录,记录的日期时间。

IdUser = 1 ; CreationDate = 2016-07-29 12:24:54.590
IdUser = 1 ; CreationDate = 2016-07-29 16:51:55.856
IdUser = 1 ; CreationDate = 2016-07-27 14:12:36.125
(151 omitted rows)

我正在寻找的是如果我能在特定用户的24小时内找到20条记录。在这个样本中,只有2个第一次是24小时。在我的情况下,我正在寻找在此期间是否有20个或更多记录。

有人可以帮助我吗? 谢谢

4 个答案:

答案 0 :(得分:6)

执行此操作(性能方面)的一种相当痛苦的方法是使用join / group byapply运算符。

从绩效角度看,apply应该更好:

select t.*
from t cross apply
     (select count(*) as cnt
      from t t2
      where t2.iduser = t.iduser and
            t2.creationdate >= t.creationdate and
            t2.creationdate < dateadd(day, 1, t.creationdate)
     ) t24
where t24.cnt >= 20;

(iduser, creationdate)上的索引是此查询的胜利。

答案 1 :(得分:0)

您是否尝试过声明DateTime变量并设置要查询的日期?

此外,如果您只想要'n'条记录,则可以使用TOP'n'CLAUSE。甚至,你可以使用TOP n%来获得百分比。 (顺便说一句,TOP从SQLServer 2008开始可用)

DECLARE @DATE DATETIME = '20160601' --YYYYMMDD

SELECT TOP 20 IdUser 
FROM MyTable
WHERE IdUser = 1 
    AND CreationDate BETWEEN DATEADD(day, -1, @DATE) AND @DATE

答案 2 :(得分:0)

您可以根据需要传递@starttime的值

DECLARE @starttime DATETIME SELECT IdUser FROM MyTable WHERE CreationDate BETWEEN @starttime and DATEADD(HOUR, 24, @starttime) GROUP BY IdUser HAVING COUNT(CreationDate) > 20

答案 3 :(得分:0)

        --This will count all records occurring 24 hours after the first instance of a record
SELECT t1.IdUser, T1.CreationDate, COUNT(0) AS InstancesIn24Hrs 
FROM MyTable t1
JOIN MyTable t2 ON T1.IdUser = T2.IdUser AND t2.CreationDate 
                     BETWEEN t1.CreationDate 
                              AND 
                             DATEADD(day, 1, t1.CreationDate) 
WHERE t1.IdUser = 1 
    GROUP BY t1.IdUser, T1.CreationDate
    ORDER BY T1.CreationDate