Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Utilisation du LAG SQL Server 2012

D'accord, tout d'abord, j'ai ajouté une ligne pour vous montrer où la réponse de quelqu'un d'autre ne fonctionne pas, mais ils l'ont supprimée maintenant.

Maintenant, pour la logique de ma requête. Vous avez dit que vous vouliez chaque ligne qui se trouve à moins de deux minutes d'une autre ligne. Cela signifie que vous devez regarder non seulement en arrière, mais aussi en avant avec LEAD(). Dans votre requête, vous avez renvoyé lorsque l'heure précédente était NULL, il a donc simplement renvoyé la première valeur de chaque OrderNumber, qu'elle soit correcte ou non. Par chance, les premières valeurs de chacun de vos OrderNumbers devaient être renvoyées jusqu'à ce que vous arriviez au dernier OrderNumber où il s'est cassé. Ma requête corrige cela et devrait fonctionner pour toutes vos données.

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

Résultats (rappelez-vous que j'ai ajouté une ligne) :

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