查找一段24小时(未尤其是最后24小时)

查找一段24小时(未尤其是最后24小时)

问题描述:

我使用的SQLServer 2012创建的记录,我有一个表时间戳这样的:查找一段24小时(未尤其是最后24小时)

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

该表记录了某种类型的操作由制造用户。
我试图找到IF用户在24小时内做了超过20次这种类型的操作(即在该表中有20个记录,该表中具有相同的IdUser)。

的问题是我没有在24小时内试图在过去的24小时内检索记录,但记录(从第1记录到今天)

这是我写的:

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

但是,WHERE条款不适合我的需要,因为我不知道该怎么翻译“征求用户ID = 1 20条记录在24小时内,没有特别的过去24小时“in 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个或更多的记录。

有人能帮助我吗?
谢谢

+0

如果你知道如何使用DATEADD(你也可以传递价值,为@starttime ),为什么不使用它来获得24小时而不是1天? –

+1

只需使用GROUP BY IdUser HAVING COUNT(CreationDate)> 20即可获取至少20个操作的用户。关于日期,您可以使用相同的日期加载函数,通过将开始或结束日期/时间作为参数 –

+0

@RamGrandhi传递,我不知道这是否会给出所需的结果,因为他的“组”可能是24小时。 –

一个相当痛苦的方式做到这一点(性能明智)是一个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)是这个查询的胜利。

+0

击败了我一拳:) – gofr1

+0

我会考虑你的答案,但我承认我从来没有使用'交叉申请',所以我会了解这些关键字。然而,这个查询将在LINQ中进行转换,因此不确定这个优化不会被LINQ“重写”... – AlexB

您是否尝试过声明DateTime变量并设置要查询的日期?另外,如果你只想'n'个记录,你可以使用TOP'n'条款。甚至,你可以使用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 

需要

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

 --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