2016-06-08 60 views
0

我有這個表在SQL中有一些列在SQL但僅限於時間段選擇不同的屬性

日期時間,用戶名,讀取ID

我需要計算的不同數量讀ID表,但只有10周分鐘的時間間隔

例如,如果我的表看起來像這樣

1 2016/06/08 15:49:10.000 user1 5859 
2 2016/06/08 15:48:39.000 user1 5859 
3 **2016/06/08 15:47:53.000 user3 5859** 
4 **2016/06/08 15:35:58.000 user1 5859** 

我希望它返回2,因爲在本例中1 2和3不1 0分鐘相隔不過3和4

例如,如果我的表看起來像這樣

1 2016/06/08 15:49:10.000 user1 5859 
2 2016/06/08 15:48:39.000 user1 5859 
3 **2016/06/08 15:47:53.000 user3 5859** 

但對於這一點,將返回1,因爲他們都是不到10分鐘的間隔

在本質上我希望它依靠不同的讀取ID,但只有當它們相隔10分鐘以上時 我不介意使用固定時間間隔(1:00,1:10,1:20 ...等)

所以我知道我可以在我的閱讀ID上做一個清晰的分類,但是對於整個桌面而言有沒有辦法模仿一個​​獨特的,但只有時間間隔?

+0

添加一些更多的樣本表中的數據,以及新的結果。 – jarlh

+0

完成。希望它更易於理解 –

+0

您使用的是哪個版本的SQL Server? – Alex

回答

0

此方法使用「桶」。下面的代碼幾輪下來時間戳最接近的10分鐘間隔:

CREATE TABLE #Test(ID INT, DT DATETIME, Username VARCHAR(50), ReadID INT) 
INSERT INTO #Test 
VALUES(
1, '2016/06/08 15:49:10.000', 'user1', 5859), 
(2, '2016/06/08 15:48:39.000', 'user1', 5859), 
(3, '2016/06/08 15:47:53.000', 'user3', 5859), 
(4, '2016/06/08 15:35:58.000', 'user1', 5859) 

SELECT * 
FROM 
    (SELECT *, 
     -- Note integer division is used to round down to nearest 10 min interval 
     DATEADD(MINUTE, DATEDIFF(MINUTE, 0, DT)/10 * 10, 0) AS TenMinuteIntervals, 
     DENSE_RANK() OVER(PARTITION BY DATEADD(MINUTE, DATEDIFF(MINUTE, 0, DT)/10 * 10, 0) ORDER BY ID) AS Duplicates 
    FROM #Test) AS Buckets 
WHERE Duplicates = 1 

輸出:

ID DT     Username ReadID 
4 2016-06-08 15:35:58.000 user1 5859 
1 2016-06-08 15:49:10.000 user1 5859 

要返回不同的讀取需要ReadID列添加到PARTION BY條款

DENSE_RANK() OVER(PARTITION BY ReadID, DATEADD(MINUTE, DATEDIFF(MINUTE, 0, DT)/10 * 10, 0) ORDER BY ID) 

要爲每個ReadID返回綜合結果,您需要添加GROUP BY

SELECT ReadID, COUNT(*) AS Cnt 
FROM 
    (SELECT *, 
     DENSE_RANK() OVER(PARTITION BY ReadID, DATEADD(MINUTE, DATEDIFF(MINUTE, 0, DT)/10 * 10, 0) ORDER BY ID) AS Duplicates 
    FROM #Test) AS Buckets 
WHERE Duplicates = 1 
GROUP BY ReadID 
0

嘗試:

;WITH cte AS (
    SELECT *, ROW_NUMBER() 
     OVER (ORDER BY dte ASC) 
    AS rn 
    FROM #t1 
) 

SELECT 
CASE 
    WHEN COUNT(id) > 0 
     THEN COUNT(id) 
    ELSE 
     1 
END AS cNt 
FROM #t1 
WHERE id IN (
    SELECT 
    id 
    FROM (
     SELECT 
      t1.id id1 
      , t2.id id2 
     FROM cte t1 
      LEFT JOIN 
      cte t2 
       ON t1.rn = t2.rn+1 
     WHERE 
      DATEDIFF(n, t2.dte,t1.dte) >= 10 
    ) cte_usage 
    UNPIVOT (
     id 
     FOR ids 
     IN (
      id1 
      , id2 
     )) AS up 
) 
相關問題