2016-07-01 16 views
0

Ich brauche alle bekommen die Room_IDs wo die Occupancy erstmals frei gemeldet werden, so nur, wenn die letzte Instanz des Occupancy frei ist und nacheinander hat während der Lebensdauer eines Room_ID in Beziehung ohne Unterbrechung gewesen zum InspectionDate(mit Ausnahme von zum Beispiel besetzt> frei> besetzt> frei oder leer> besetzt oder frei> besetzt> frei> frei, aber einschließlich vakanten> vakant)TSQL: Erster Instanz von X

Dies ist eine vereinfachte Tabelle I als Beispiel verwenden:

Room_Id inspection_ID Occupancy InspectionDate 
---------------------------------------------------- 
    1  11    vacant  5/15/2015 
    1  12    occupied  5/21/2015 
    1  13    vacant  9/19/2015 
    1  14    occupied  1/16/2016 
    2  21    vacant  3/25/2015 
    2  22    occupied  8/27/2015 
    2  23    occupied  4/17/2016 
    3  31    occupied 12/12/2015 
    3  32    occupied  3/22/2015 
    3  33    vacant  2/2/2016 
    3  34    occupied  3/24/2016 
    4  41    occupied  4/17/2015 
    4  42    occupied 11/12/2015 
    4  43    occupied 12/22/2015 
    4  44    vacant  2/2/2016 
    4  45    vacant  3/24/2016 
    5  45    vacant  3/24/2015 
    5  45    vacant  3/24/2016 

Mein Ergebnis sollte wie folgt aussehen:

Room_Id inspection_ID Occupancy InspectionDate 
--------------------------------------------------- 
    4  41    occupied  4/17/2015 
    4  42    occupied 11/12/2015 
    4  43    occupied 12/22/2015 
    4  44    vacant  2/2/2016 
    4  45    vacant  3/24/2016 
    5  45    vacant  3/23/2015 
    5  45    vacant  3/24/2016 

Bitte lassen Sie mich wissen, wenn es nicht klar genug ist.

+1

Mögliches Duplikat von [TSQL: die obersten Datensätze einer bestimmten Partition (bedingt)] (http://stackoverflow.com/questions/38112133/tsql-the-top-records-of-a-iven-partition-conditional) –

+0

@AlexKudryashev schließen, aber nicht ganz das gleiche, dass man sieht, ob die 2 letzten Datensätze für jede Instanz der ID frei sind .. dieser sucht nach FTVs –

Antwort

0
select * from T where Room_ID in ( 
    select Room_ID from T 
    group by Room_ID 
    having 
      coalesce(
       max(case when occupancy = 'occupied' then InspectionDate end), 
       cast('19000101' as date) 
     ) < 
      min(case when occupancy = 'vacant' then InspectionDate end) 
); 

Wenn die having Bedingung wahr ist, dann alle der vacants erscheinen später als die occupieds (oder ein Dummy-Datum, wenn keine vorhanden sind.)

Hier ist der gleiche Ansatz Analytik:

select * from 
( 
    select *, 
     max(case when occupancy = 'occupied' then InspectionDate end) 
      over (partition by Room_ID, occupancy) as max_o 
     min(case when occupancy = 'vacant' then InspectionDate end) 
      over (partition by Room_ID, occupancy) as min_v 
    from T 
) t 
where max_o < min_v or max_o is null and max_v is not null; 

Überprüfen Sie die Pläne und sehen Sie, welche besser funktioniert.