如何根据上一行和当前行之间的时间间隔删除行

时间:2014-09-15 07:28:05

标签: sql ssms intervals

在数据库中,我通过点击它来跟踪某个项目被激活的时间戳。但是,由于应用程序前端的滞后,人们有时会在某个项目上点击很多。我想要做的是找到有效点击量,这意味着我想从表中删除与前一行相差3秒的行。

表#tmp

Klant_id    Timestamp               Item_id     Sitecore_id Delete?
5387        2014-05-27 21:37:03.000 66          396         
5387        2014-05-27 21:37:07.000 66          396         
5387        2014-05-27 21:37:08.000 66          396         YES
5387        2014-05-27 21:37:11.000 66          396         YES 
5387        2014-05-27 21:37:14.000 66          396         YES 
5387        2014-05-27 21:37:30.000 66          396
5387        2014-05-27 21:37:31.000 66          396         YES
5387        2014-05-27 21:37:33.000 66          396         YES
5387        2014-05-27 21:37:39.000 66          396 
5387        2014-05-27 21:37:40.000 66          396         YES
5387        2014-05-27 21:38:15.000 66          396 
5387        2014-05-27 21:38:23.000 66          396
5387        2014-05-27 21:38:37.000 66          396 
5387        2014-05-27 21:35:37.000 69          402 
5387        2014-05-27 21:35:41.000 69          402 
5387        2014-05-27 21:35:42.000 69          402         YES
5387        2014-05-27 21:35:44.000 69          402         YES
5387        2014-05-27 21:35:46.000 69          402         YES 
5387        2014-05-27 21:37:57.000 69          402
5387        2014-05-27 21:38:01.000 69          402 
5387        2014-05-27 21:38:03.000 69          402         YES 
5387        2014-05-27 21:38:04.000 69          402         YES 
5387        2014-05-27 21:38:35.000 99          434

这可能是一个非常简单的问题,但我不知道如何编写调用前一行的代码。

据我所知。

    SELECT  *
    ,CAST(KLANT_ID AS VARCHAR)+'-'+VBSN+'-'+CAST(INFOITEM_ID AS VARCHAR)+'-'+SITECORE_ID AS KEY
    ,ROW_NUMBER()OVER(PARTITION BY KLANT_ID, VBSN, INFOITEM_ID, SITECORE_ID ORDER BY TIMESTAMP ASC) AS COUNTER
INTO   #TMP1
FROM   #TMP

    SELECT  A.*
    ,DATEDIFF(MILLISECOND, B. TIMESTAMP,A. TIMESTAMP) AS INTERVAL
    ,B.TIMESTAMP
INTO    #TMP2
FROM    #TMP1 A
INNER JOIN #TMP1 B
ON A.KEY = B.KEY
WHERE   1=1
AND     B.COUNTER = (A.COUNTER + 1)

DELETE FROM #TMP2 WHERE INTERVAL > 3001

提前致谢。

Jurre

2 个答案:

答案 0 :(得分:1)

代码

WITH A AS (SELECT [Klant_id]
      ,[Timestamp]
      ,[PriorTimestamp]
      ,CASE WHEN [PriorTimestamp]=0 THEN 999 ELSE DATEDIFF(ss, [PriorTimestamp], [Timestamp]) END AS [Timediff]
      ,[Item_id]
      ,[Sitecore_id]
FROM (SELECT [Klant_id]
              ,[Timestamp]
              ,ISNULL(LAG([TimeStamp]) OVER (PARTITION BY Item_id ORDER BY Timestamp), 0) AS [PriorTimestamp]
              ,[Item_id]
              ,[Sitecore_id] FROM #tmp) AS B
WHERE CASE WHEN [PriorTimestamp]=0 THEN 999 ELSE DATEDIFF(ss, [PriorTimestamp], [Timestamp]) END <=3)
DELETE #tmp FROM #tmp INNER JOIN A ON #tmp.[Timestamp]=A.[Timestamp]
WHERE A.[Timestamp]=#tmp.[TimeStamp]

理论

使用递归CTE查找每个Item_id的连续时间戳之间的差异(您可以根据需要添加其他条件),然后从表中删除相隔3秒或更短秒的每个实例。

答案 1 :(得分:0)

希望我做对了!

SELECT  *
INTO    #TMP
FROM    IMPORTINFOKANAAL

UNION
SELECT  Klant_id, VBSN, Timestamp, InfoItem_id, SiteCore_id, ImportDatum
    FROM    IMPORTINFOKANAAL_ARCHIEF
;

SELECT  *
        ,ROW_NUMBER() OVER(PARTITION BY Klant_id, VBSN, InfoItem_id, SiteCore_id ORDER BY TIMESTAMP) AS TELLER
    INTO    #TMP2
    FROM    #TMP

;

WITH A AS
(
    SELECT  KLANT_ID
        ,TIMESTAMP
        ,INFOITEM_ID
        ,SITECORE_ID
        ,CASE
            WHEN TIMEDIFF = 0 THEN 999
            ELSE TIMEDIFF
        END AS TIMEDIFF
    FROM    (SELECT T1.KLANT_ID AS KLANT_ID
                    ,T1.TIMESTAMP AS TIMESTAMP
                    ,T1.InfoItem_id
                    ,T1.SiteCore_id
                    ,CASE
                        WHEN ABS(DATEDIFF(SECOND,T1.TIMESTAMP,T2.TIMESTAMP)) IS NULL THEN 0
                        ELSE ABS(DATEDIFF(SECOND,T1.TIMESTAMP,T2.TIMESTAMP))
                    END AS TIMEDIFF
                FROM    #TMP2 AS T1
                LEFT JOIN #TMP2 AS T2
                ON      T1.KLANT_ID = T2.KLANT_ID
                AND     T1.InfoItem_id = T2.INFOITEM_ID
                AND     T1.SITECORE_ID = T2.SiteCore_id
                AND     T1.TELLER = (T2.TELLER - 1)
            ) AS B
    WHERE   1=1
    AND     CASE
                WHEN TIMEDIFF = 0 THEN 999
                ELSE TIMEDIFF
            END < 3
)
DELETE #TMP2 
FROM    #TMP2 AS T3
INNER JOIN A AS T4
ON      T3.Timestamp = T4.TIMESTAMP
AND     T3.KLANT_ID = T4.KLANT_ID
AND     T3.InfoItem_id = T4.InfoItem_id
AND     T3.SiteCore_id = T4.SiteCore_id

WHERE   1=1
AND     T3.Timestamp = T4.TIMESTAMP