2015-09-04 13 views
5

Se ho un programma presso un'officina e voglio selezionare tutte le auto nella mia tabella di RepairOrder dove il chilometraggio dell'ordine di riparazione successivo è inferiore al chilometraggio dell'ordine di riparazione precedente, come posso costruire quell'istruzione selezionata?Come posso selezionare le righe in cui il numero è andato giù come data è salito

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 questo caso sarei selezionando solo VehicleID 1 perché ha un RepairDate che è maggiore della riga precedente, ma un chilometraggio che è inferiore alla riga precedente. Potrebbero esserci anche 3 file con lo stesso veicolo e la data centrale ha un chilometraggio di 3 o 5000000, e dovrò selezionare anche quelle di VehicleID.

risultati di utilizzare la funzione LEAD()

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

Non capisco il campione 3 righe, si potrebbe approfondire o includere sui dati di esempio come macchina 5. Anche ciò che RDBMS stai usando? –

+0

Sto usando il server Sql con ssms e ho appena aggiunto i dati per te. Quindi la query dovrebbe selezionare anche vehicleID 5 poiché la riparazione centrale ha un chilometraggio inferiore alla riga precedente. E avrei anche dovuto dire 3 o più righe. Potrebbero esserci 10 ordini di riparazione per 1 veicolo, e 1 dei chilometraggi è rovinato e devo segnalarlo. – IQtheMC

+0

quale versione di SQL Server? quindi questo è solo per rilevare l'errore dei dati. Ma poi vuoi Vehicle ID o ID dove si verifica l'errore? –

risposta

0

Non è terribilmente efficace, ma si poteva fare una selezione a coppie

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

è probabile una soluzione migliore come selezioni coppie ottengono ESTREMAMENTE LENTO, ma questo dovrebbe funzionare così com'è.

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

Questo è un ottimo posto per usare LEAD() funzione per SQL 2014+

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 

La mia soluzione mostra tutte le colonne in modo da poter verificare cosa fila hanno il problema.

Inoltre, evito di utilizzare distinct perché, come suggeriscono OP, potrebbero esserci diversi errori per la stessa macchina e in questo modo è possibile vederli tutti. enter image description here

+0

'LEAD()' è disponibile anche nel 2012 – mheptinstall

+0

@mheptinstall Hai ragione. Prima riga in [_microsoft page_] (https://msdn.microsoft.com/en-us/library/hh213125.aspx) dire Applica al 2014+ ma poi al successivo paragrafo dici 'Si applica a: SQL Server (SQL Server 2012 attraverso corrente versione), ' –

+0

Questi sicuramente non sono i risultati giusti. Alcuni ID veicolo compaiono solo una volta, e alcuni degli altri ID veicolo che compaiono due volte hanno un chilometraggio maggiore nella data più grande, e altri ID veicolo che compaiono due volte hanno un chilometraggio minore nella data più grande. Questi sono i primi risultati restituiti. – 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

Mentre questa potrebbe essere una soluzione eccezionale al problema, si prega di considerare l'aggiunta di alcuni chiarimenti sul perché questa è una buona risposta e che cosa fa. –

Problemi correlati