使用SQL Server 2012 LAG

时间:2015-04-21 22:09:13

标签: sql sql-server sql-server-2012

我正在尝试使用SQL Server 2012 LAG函数编写一个查询来从我的[Order]表中检索数据,其中一行与上一行之间的日期时间差小于等于2分钟。

我期待的结果是

1234    April, 28 2012 09:00:00

1234    April, 28 2012 09:01:00

1234    April, 28 2012 09:03:00

5678    April, 28 2012 09:40:00

5678    April, 28 2012 09:42:00

5678    April, 28 2012 09:44:00

但我正在看

1234    April, 28 2012 09:00:00

1234    April, 28 2012 09:01:00

1234    April, 28 2012 09:03:00

5678    April, 28 2012 09:40:00

5678    April, 28 2012 09:42:00

5678    April, 28 2012 09:44:00

91011   April, 28 2012 10:00:00

不应返回最后一行。以下是我尝试过的内容:SQL Fiddle

有想法的人吗?

1 个答案:

答案 0 :(得分:3)

好的,首先我添加了一行来向您显示其他人的答案无效但他们现在已将其删除。

现在查询我的逻辑。你说你希望每一行都在另一行的两分钟之内。这意味着您不仅要向后看,还要用LEAD()进行前锋。在您的查询中,您在前一个时间为NULL时返回,因此它只返回每个OrderNumber的第一个值,无论它是对还是错。偶然的情况下,每个OrderNumbers的第一个值都需要返回,直到你到达它破坏的最后一个OrderNumber。我的查询更正了这一点,并且应该适用于您的所有数据。

CREATE TABLE [Order]  
    (
            OrderNumber    VARCHAR(20) NOT NULL
        ,   OrderDateTime   DATETIME NOT NULL
    );

    INSERT [Order] (OrderNumber, OrderDateTime) 
    VALUES
        ('1234', '2012-04-28 09:00:00'),
        ('1234', '2012-04-28 09:01:00'),
        ('1234', '2012-04-28 09:03:00'),
        ('5678', '2012-04-28 09:40:00'),
        ('5678', '2012-04-28 09:42:00'),
        ('5678', '2012-04-28 09:44:00'),
        ('91011', '2012-04-28 10:00:00'),
        ('91011', '2012-04-28 10:25:00'),
        ('91011', '2012-04-28 10:27:00');

with Ordered as (
  select
    OrderNumber,
    OrderDateTime,
    LAG(OrderDateTime,1) over (
      partition by OrderNumber
      order by OrderDateTime
    ) as prev_time,
    LEAD(OrderDateTime,1) over (
      partition by OrderNumber
      order by OrderDateTime
    ) as next_time
  from [Order]
)

SELECT  OrderNumber,
        OrderDateTime
FROM Ordered
WHERE   DATEDIFF(MINUTE,OrderDateTime,next_time) <= 2  --this says if the next value is less than or equal to two minutes away return it
        OR DATEDIFF(MINUTE,prev_time,OrderDateTime) <= 2 --this says if the prev value is less than or equal to 2 minutes away return it

结果(请记住我添加了一行):

OrderNumber          OrderDateTime
-------------------- -----------------------
1234                 2012-04-28 09:00:00.000
1234                 2012-04-28 09:01:00.000
1234                 2012-04-28 09:03:00.000
5678                 2012-04-28 09:40:00.000
5678                 2012-04-28 09:42:00.000
5678                 2012-04-28 09:44:00.000
91011                2012-04-28 10:25:00.000
91011                2012-04-28 10:27:00.000