2016-07-29 120 views
3

我使用的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小時。 –

回答

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)是這個查詢的勝利。

+0

擊敗了我一拳:) – gofr1

+0

我會考慮你的答案,但我承認我從來沒有使用'交叉申請',所以我會了解這些關鍵字。然而,這個查詢將在LINQ中進行轉換,因此不確定這個優化不會被LINQ「重寫」... – AlexB

0

您是否嘗試過聲明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 
0

需要

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

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