2015-09-04 2 views
5

Wenn ich ein Programm in einer Reparaturwerkstatt habe und alle Autos in meiner RepairOrder - Tabelle auswählen möchte, ist die Laufleistung des späteren Reparaturauftrags geringer als die Kilometerstand des vorherigen Reparaturauftrags, wie kann ich diese Select-Anweisung erstellen?Wie kann ich Zeilen auswählen, in denen die Zahl mit steigendem Datum gesunken ist?

ID VehicleID Mileage RepairDate 
01 1   18425 2013-08-13 
02 1   28952 2013-02-26 
03 2   22318 2012-08-27 
04 3   21309 2012-08-07 
05 3   16311 2012-02-27 
06 3   16310 2012-02-11 
07 4   11098 2011-03-23 
08 5   21309 2012-08-07 
09 5   16309 2012-02-27 
10 5   16310 2012-02-11 

In diesem Fall soll ich nur VehicleID 1 Auswahl werden, weil es eine RepairDate hat, die größer als die vorherige Zeile, sondern ein Kilometerstand, die kleiner als die vorhergehende Zeile ist. Es könnte auch 3 Reihen mit demselben Fahrzeug geben und das mittlere Datum hätte eine Laufleistung von 3 oder 5000000, und ich werde auch diese Fahrzeug-IDs auswählen müssen.

Ergebnisse der LEAD() Funktion

ID RepairDate Mileage 
25 2011-12-23 45934 
48 2009-02-26 13 
48 2009-04-24 10 
71 2011-07-26 31163 
71 2015-01-13 65656 
+0

ich nicht Ihre 3 Reihen Probe verstehen, könnten Sie es auf den Beispieldaten als Auto 5. Auch erarbeiten oder beinhalten, was rdbms sind Sie mit? –

+0

Ich benutze SQL-Server mit SSM, und ich habe nur die Daten für Sie hinzugefügt. Daher sollte die Abfrage auch die Fahrzeug-ID 5 auswählen, da die mittlere Reparatur eine geringere Kilometerleistung hat als die davor liegende Zeile. Und ich hätte auch 3 oder mehr Zeilen sagen sollen. Es könnte 10 Reparaturaufträge für 1 Fahrzeug geben, und 1 der Kilometer ist vermasselt und ich muss es kennzeichnen. – IQtheMC

+0

Welche Version von SQL Server? das ist also nur Datenfehler zu erkennen. Aber dann wollen Sie VehiculeID oder ID wo Fehler passieren? –

Antwort

0

Es ist nicht sehr effizient verwenden, aber man konnte eine paarweise Auswahl

select t1.VehicleID 
from table t1, table t2 
where t1.VehicleId = t2.VehicleId 
AND t1.Mileage > t2.Mileage 
AND t1.RepairDate < t2.RepairDate 

Es ist wahrscheinlich eine bessere Lösung als paarweise Auswahlen zu tun bekommen EXTREM LANGSAM, aber das sollte funktionieren wie es ist.

0
select distinct RO.VehicleID 
from RepairOrder RO 
where exists(select * 
      from RepairOrder 
      where ID != RO.ID 
      and VehicleID = RO.VehicleID and RepairDate > RO.RepairDate 
      and Mileage < RO.Mileage); 
0
WITH RepairSeqs AS(
    SELECT 
     DateSeq = Row_Number OVER (PARTITION BY VehicleID ORDER BY RepairDate), 
     MileageSeq = Row_Number OVER (PARTITION BY VehicleID ORDER BY Mileage), 
     * 
    FROM 
     dbo.RepairOrder 
) 
SELECT * 
FROM RepairSeqs 
WHERE DateSeq <> MileageSeq; 
2

Dies ist ein großartiger Ort LEAD() Funktion für 2014+ SQL verwenden

SQL FIDDLE DEMO

WITH NextM as (
    SELECT 
     * , 
     LEAD(Mileage, 1, null) over (partition by VehicleID order by RepairDate) NextMileage 
    FROM RepairOrder 
) 
SELECT * 
FROM NextM 
WHERE Mileage > NextMileage 

Meine Lösung zeigen alle Spalten so können Sie überprüfen, welche Zeile das Problem.

Auch ich vermeide die Verwendung distinct, weil wie OP vorschlagen, es kann mehrere Fehler für das gleiche Auto geben und auf diese Weise können Sie alles sehen. enter image description here

+0

'LEAD()' ist auch im Jahr 2012 verfügbar – mheptinstall

+0

@mheptiminstall Sie haben Recht. Erste Zeile in [_microsoft page_] (https://msdn.microsoft.com/en-us/library/hh213125.aspx) heißt Apply to 2014+, aber dann paragraph sagen 'Gilt für: SQL Server (SQL Server 2012 durch aktuelle Version), ' –

+0

Diese sind definitiv nicht die richtigen Ergebnisse. Einige Fahrzeug-IDs erscheinen nur einmal, und einige der anderen Fahrzeug-IDs, die zweimal erscheinen, haben am größeren Datum eine größere Laufleistung, und andere Fahrzeug-IDs, die zweimal erscheinen, haben am größeren Datum eine geringere Laufleistung. Dies sind die ersten Ergebnisse, die zurückgegeben werden. – IQtheMC

0
select distinct t.VehicleId 
from (
select t.*, LEAD(Mileage) OVER (Partition by VehicleId ORDER BY RepairDate) LeadMileageValue 
from RepairOrder t 
) t 
where t.Mileage > t.LeadMileageValue 
+0

Während dies eine großartige Lösung für das Problem sein könnte, ziehen Sie bitte eine Klarstellung darüber, warum dies eine gute Antwort ist und was es tut. –

Verwandte Themen