2016-10-28 2 views
2

sequentiell Ich habe eine Tabelle mit Daten, die wie folgt aussieht:SQL Server: Hier finden Sie Zeilen in der Tabelle, wo beide Spalten nicht

pK Customer  DateTime1     DateTime2 
1  6   2016-04-01 00:00:00.000 2016-10-09 00:00:00.000 
2  6   2016-07-01 00:00:00.000 2016-10-21 00:00:00.000 
3  6   2016-10-01 00:00:00.000 2016-10-20 00:00:00.000 

Ich möchte Zeilen zu finden, wo, wann DateTime1 bestellt wird, den Wert des entsprechenden DateTime2 (wenn nach Kunden-ID gefiltert) folgen nicht der gleichen Reihenfolge.

So im Fall oben I mit pK 3 als Zeile finden möchte, wenn DateTime1 bestellt aufsteigend, dann DateTime2 nicht größer als DateTime2 in Reihe 2.

Es scheint auf diese Frage ähnlich, aber es handelt mit der Reihenfolge der Elemente eher dann Ungleichheit: TSQL check if specific rows sequence exists

ich habe versucht, eine Version der Anweisung CTE mit

+0

Die Formulierung Ihrer Frage ist ein wenig verwirrend. "... folgt nicht auch der gleichen Reihenfolge". Könnten Sie bitte klarstellen, was Sie meinen? – jhilden

+0

Aktualisiert die Frage, danke. – CorribView

Antwort

2
Declare @YourTable table (pK int,Customer int,DateTime1 datetime,DateTime2 datetime) 
Insert Into @YourTable values 
(1,6,'2016-04-01 00:00:00.000','2016-10-09 00:00:00.000'), 
(2,6,'2016-07-01 00:00:00.000','2016-10-21 00:00:00.000'), 
(3,6,'2016-10-01 00:00:00.000','2016-10-20 00:00:00.000') 

;with cte as (
    Select *,Flg=Row_Number() over (Partition By Customer Order By DateTime1) - Row_Number() over (Partition By Customer Order By DateTime2) 
    From @YourTable 
) 
Select pK 
     ,Customer 
     ,DateTime1 
     ,DateTime2 
From cte 
Where Flg>0 

Returns

pK Customer DateTime1    DateTime2 
3 6   2016-10-01 00:00:00.000 2016-10-20 00:00:00.000 
+0

Großartig, genau das habe ich gesucht! – CorribView

+0

@CorribView Glücklich zu helfen –

0

Dies scheint eine große Anwendung von row_number() zu sein:

select t.* 
from (select t.*, 
      row_number() over (partition by customer order by datetime1) as seqnum_1, 
      row_number() over (partition by customer order by datetime2) as seqnum_2 
     from t 
    ) t 
where seqnum_1 <> seqnum_2; 

Dies würde aber alle falsch geordneten Zeilen zurück, auf der Grundlage der globalen Ordnung (pk 2 und 3 in diesem Fall).

Sie wollen einfach nur, wo die Richtung auf einer gegebenen Zeile ändert. Dafür verwenden lag():

select t.* 
from (select t.*, 
      lag(datetime1) over (partition by customer order by pk) as prev_dt1, 
      lag(datetime2) over (partition by customer order by pk) as prev_dt2 
     from t 
    ) t 
where (dt1 > prev_dt1 and dt2 <= prev_dt2) or 
     (dt1 < prev_dt1 and dt2 >= prev_dt2); 
+0

Danke für die Antwort, aber die andere Antwort hat genauer gesagt, was ich gesucht habe. – CorribView

+0

@CorriBiew. . . Das "lag()" scheint genau das zu sein, wonach Sie suchen. –

Verwandte Themen