DATEDIFF基于WHERE子句中的ID

时间:2016-04-07 02:10:57

标签: sql sql-server-2012

我尝试根据以下条件从查询中排除行。

  
      
  1. 计算EID为33到49之间的时差
  2.   
  3. 如果总秒数小于35,则将其从查询中排除
  4.   
SELECT c1.* FROM CTE2 C2
INNER JOIN CTE C1
ON C2.ID = C1.ID
AND c1.EID IN (33,49)
ORDER BY C1.ID, C1.DateTime

我的数据可能包含具有重复EID=33的相同ID的多个行,但它始终只有一个EID=49。因此,对于同一ID的ID减去last record行,我感兴趣previous。如果小于35秒,则从结果中排除此ID

我尝试使用Lag函数并在上面的查询中添加AND语句

AND DATEDIFF(SECOND, DateTime, LAG(datetime) OVER (ORDER BY id, datetime)) < 35

但是我收到以下错误:

  

窗口函数只能出现在SELECT或ORDER BY子句中。

我确实尝试过不同的方法:

;with cte AS 
(
   SELECT *,ROW_NUMBER() OVER(PARTITION BY id ORDER BY DateTime) AS RN 
   FROM @cte WHERE eid IN (33,49)
)
SELECT a.*, DATEDIFF(SECOND,a.datetime, b.DateTime) AS diff
FROM cte a
LEFT JOIN cte b
ON a.id = b.id
AND a.RN = b.RN -1
AND DATEDIFF(second, a.DateTime, b.DateTime) < 35

但仍然没有给我正确的数据。

这是一个样本记录。

enter image description here

根据此记录,它应该只返回ID=12345并排除ID=54321,因为差异只有12秒。

有什么建议吗?

更新

我无法创建SQLFIDDLE。这是一个创建TEMP表的SCRIPT。

DECLARE @cte as table 
(
   ID Char (5),
   [DateTime]  DateTime,
   EID integer
)

INSERT INTO @cte
VALUES
( N'12345', N'2016-03-15 13:14:57.000', 1 ), 
( N'12345', N'2016-03-15 13:15:01.000', 2 ), 
( N'12345', N'2016-03-15 13:15:12.000', 5 ), 
( N'12345', N'2016-03-15 13:15:13.000', 12 ), 
( N'12345', N'2016-03-15 13:15:13.000', 13 ), 
( N'12345', N'2016-03-15 13:15:27.000', 16 ), 
( N'12345', N'2016-03-15 13:15:27.000', 22 ), 
( N'12345', N'2016-03-15 13:15:27.000', 23 ), 
( N'12345', N'2016-03-15 13:15:39.000', 26 ), 
( N'12345', N'2016-03-15 13:15:39.000', 32 ), 
( N'12345', N'2016-03-15 13:15:42.000', 52 ), 
( N'12345', N'2016-03-15 13:15:42.000', 33 ), 
( N'12345', N'2016-03-15 13:15:52.000', 48 ), 
( N'12345', N'2016-03-15 13:16:37.000', 33 ), 
( N'12345', N'2016-03-15 13:17:13.000', 35 ), 
( N'12345', N'2016-03-15 13:17:13.000', 49 ), 
( N'54321', N'2016-03-24 20:55:30.000', 1 ), 
( N'54321', N'2016-03-24 20:55:30.000', 50 ),  
( N'54321', N'2016-03-24 20:55:32.000', 2 ), 
( N'54321', N'2016-03-24 20:56:30.000', 5 ), 
( N'54321', N'2016-03-24 20:56:30.000', 12 ), 
( N'54321', N'2016-03-24 20:56:30.000', 13 ), 
( N'54321', N'2016-03-24 20:57:44.000', 16 ), 
( N'54321', N'2016-03-24 20:57:44.000', 22 ), 
( N'54321', N'2016-03-24 20:57:44.000', 23 ), 
( N'54321', N'2016-03-24 20:57:56.000', 26 ), 
( N'54321', N'2016-03-24 20:57:56.000', 32 ), 
( N'54321', N'2016-03-24 20:57:59.000', 52 ), 
( N'54321', N'2016-03-24 20:58:54.000', 33 ), 
( N'54321', N'2016-03-24 20:59:06.000', 35 ), 
( N'54321', N'2016-03-24 20:59:06.000', 49 )

2 个答案:

答案 0 :(得分:4)

如何使用聚合?假设33s总是在49之前(这似乎是基于样本数据的情况):

select id
from @cte
group by id
having datediff(second,
                max(case when eid = 33 then datetime end),
                max(case when eid = 49 then datetime end)
               ) < 35;

答案 1 :(得分:1)

使用条件聚合和IN

WITH Cte AS(
    SELECT
        ID,
        MAX33 = MAX(CASE WHEN EID = 33 THEN DateTime END),
        MAX49 = MAX(CASE WHEN EID = 49 THEN DateTime END)
    FROM @cte
    WHERE EID IN(33, 49)
    GROUP BY ID
)
SELECT * 
FROM @cte
WHERE ID IN(
    SELECT ID
    FROM Cte
    WHERE ABS(DATEDIFF(SECOND, MAX33, MAX49)) >= 35
)