2013-08-01 12 views
18

Jestem tu nowy na stronie i potrzebuję pomocy od was. Poniżej znajduje się schemat, który mogę uruchomić na tej stronie http://sqlfiddle.com/#!3/134c3. Nazwa mojej bazy danych to kontrole pojazdów. Moje pytanie dotyczy tego schematu.Warunki IF IF z innych tabel

CREATE TABLE Car 
    ([CarID] varchar(36), 
    [PlateNo] varchar(6), 
    [Package] int); 

    INSERT INTO Car([CarID], [PlateNo], [Package]) 
    VALUES('A57D4151-BD49-4B44-AF10-000F1C298E05', '8112AG', 4); 

    CREATE TABLE Event  
    ([EventID] int, 
    [CarID] varchar(36), 
    [EventTime] smalldatetime, 
    TicketStatus varchar (10)) ;  

INSERT INTO Event([EventID], [CarID], [EventTime], TicketStatus) 
VALUES (1, 'A57D4151-BD49-4B44-AF10-000F1C298E05', '20130701', 'Open'), 
     (2, 'A57D4151-BD49-4B44-AF10-000F1C298E05', '20130702', 'Close') ; 

CREATE TABLE EventDefects 
    ([EventDefectsID] int, 
    [EventID] int, 
    [Status] varchar(15), 
    [DefectID] int) ; 

INSERT INTO EventDefects ([EventDefectsID], [EventID], [Status], [DefectID]) 
VALUES (1, 1, 'YES', 1), 
     (2, 1, 'NO', 2), 
     (3, 1, 'N/A', 3), 
     (4, 1, 'N/A', 4), 
     (5, 2, 'N/A', 1), 
     (6, 2, 'N/A', 2), 
     (7, 2, 'N/A', 5), 
     (8, 2, 'YES', 3), 
     (9, 2, 'NO', 4) ; 

CREATE TABLE Defects 
    ([DefectID] int, 
    [DefectsName] varchar (36), 
    [DefectClassID] int) ; 

INSERT INTO Defects ([DefectID], [DefectsName], [DefectClassID]) 
VALUES (1, 'TYRE', 1), 
     (2, 'BRAKING SYSTEM', 1), 
     (3, 'OVER SPEEDING', 3), 
     (4, 'NOT WEARING SEATBELTS', 3), 
     (5, 'MIRRORS AND WINDSCREEN', 2) ; 

CREATE TABLE DefectClass 
    ([Description] varchar (15), 
    [DefectClassID] int) ; 

INSERT INTO DefectClass ([DefectClassID], [Description]) 
VALUES (1, 'CATEGORY A'), 
     (2, 'CATEGORY B'), 
     (3, 'CATEGORY C') 

Aby wyjaśnić pewne kwestie. Istnieją dwa warunki, w których wydajemy bilet kierowcy.

  1. Kiedy pojazd jest sprawdzony i stwierdzono defektów jakichkolwiek przedmiotów należących do klasy A lub B (zaznaczyć „tak”). Status biletu jest OTWARTY. Z drugiej strony, jeśli wszystkie pozycje w klasie A i B mają wartość "Nie", oznacza to, że nie znaleziono żadnych wad. Status biletu to ZAMKNIJ. Wreszcie pozycje w klasie C lub (wykroczenia drogowe) są zaznaczone N/A. Oznacza to, że jest to zwykła inspekcja pojazdu:

  2. Warunek nr 2 to miejsce zatrzymania pojazdu z powodu wykroczeń drogowych (np. Nadmierna prędkość). Pojazd NIE zostanie poddany kontroli, Rozróżnienie tego wydanego biletu to wszystkie przedmioty w klasie A i B to znak "N/A", natomiast w klasie C oznacza "tak" lub "nie".

Teraz mam ten kod SQL poniżej, które mogą być użyte w schemacie powyżej, gdzie będzie wyodrębnić pojazdów na swym MAX(EventTime) z odpowiednim status biletu.

Select 
     PlateNo, TicketStatus, [EventTime] 
    FROM 
     (SELECT 
     ROW_NUMBER() OVER (PARTITION BY Event.CarID ORDER BY [EventTime] DESC) AS [index], 
     Event.CarID, 
     TicketStatus, 
     [EventTime], 
     plateNo 
     FROM 
     [Event] 
     Join 
     [Car] ON Event.CarID = Car.CarID) A 
    WHERE [index] = 1 

Wynik:

RESULT: PlateNo - 8112AG ; EventTime - July 2, 2013; TicketStatus - Close. 

TO NIE jest poprawny, ponieważ w tym konkretnym dniu nie było kontroli w ogóle tylko kierowca został zatrzymany za przekroczenie prędkości (patrz schemat powyżej) i przedmiotów należących do klasy A i B są oznaczone jako Nie dotyczy.

Prawidłowy wynik powinien wynosić jeden krok wstecz, tj. 1 lipca 2013 r., A status biletu jest OTWARTY, ponieważ był to przejrzysty przegląd. Przedmioty należące do kategorii A i B są sprawdzane i stwierdzone, że OPONY są uszkodzone, a SYSTEM HAMULCOWY NIE ma żadnych wad.

Jakimś sposobem wymyśliłem kod, w przypadku gdy Event.TicketStatus = CLOSE zbada, czy jest blisko, ponieważ został sprawdzony lub zamknięty, ponieważ jest to naruszenie przepisów ruchu drogowego.

+0

Możesz użyć '* italic *' lub '** bold **' do podkreślenia słów. – GolezTrol

+4

Dobrze sformułowane pytanie dla nowicjusza ... – ganders

+0

Czy musisz zmienić klauzulę where, aby sprawdzić, gdzie [index] = 2? – ganders

Odpowiedz

1

Spróbuj tego.

SELECT 
    PlateNo, 
    TicketStatus, 
    MAX(EventTime) 
FROM 
    [Event] E 
LEFT OUTER JOIN 
    [EventDefects] ED ON E.EventID = ED.EventID 
LEFT OUTER JOIN 
    [Defects] D ON ED.DefectID = D.DefectID 
LEFT OUTER JOIN 
    [Car] C ON E.CarID = C.CarID 
WHERE ED.Status = 'YES' AND D.DefectClassID <> 3 
GROUP BY PlateNo, TicketStatus 
+0

seekerOfKnowledge, dziękuję za twój kod, ale wystąpił problem, gdy dodałem dodatkowe dane do wspomnianego PlateNo, które jest kolejną inspekcją lub EventTime, czyli 3 lipca 2013 r. , Lusterka i szyba przednia = TAK (co oznacza wadę). A TicketStatus jest otwarty.Kiedy uruchomię twój kod, dwa wiersze tego samego PlateNo na ich różnych EventTime jest wynikiem. To, co chcę uzyskać, to Max (EventTime), którego wynikiem jest inspekcja z 3 lipca 2013 r. – user2642629

+0

@ user2642629 Przepraszam za to. Zmieniono moją odpowiedź na twoje potrzeby. – seekerOfKnowledge

+0

@ user2642629 po pewnych prawidłowych testach, następna próba. – seekerOfKnowledge

1

myślę, że można rozwiązać w ten sposób:

SELECT C.PlateNo, E.EventID, E.TicketStatus, E.EventTime 
FROM Car C 
INNER JOIN Event E ON C.CarID = E.CarID 
INNER JOIN (
SELECT CarID, MAX(E.EventTime) EventTime FROM Event E 
    LEFT JOIN EventDefects ED ON E.EventID = ED.EventID 
    LEFT JOIN Defects D ON ED.DefectID = D.DefectID 
      WHERE D.DefectClassID IN (1,2) AND ED.Status <> 'N/A' 
GROUP BY CarID 
) T ON E.CarID = T.CarID AND E.EventTime = T.EventTime 

Podzapytanie filtruje wszystkie zdarzenia w klasie 1 i 2 (kontroli) i gdzie coś się stało (<> 'N/A') , i robi to na maksimum, więc przyniesie ostatnie zdarzenie prawdziwej inspekcji każdego samochodu. Następnie jest połączenie, które doprowadza stan do tej daty. Z tego, co zrozumiałem, tego właśnie chcesz, prawda?