2012-10-29 8 views
6

Oto problem w trybie szczegółowym. Mam instancje certyfikatów na tabeli certyfikacji i wszystkie one mają typ i ucznia z nimi związane. Oto, co chcę zrobić, chcę pobrać wszystkie certyfikaty z datą wygaśnięcia mieszczącą się w zakresie dat (TERAZ do 1 roku). Jeśli kwalifikują się do tego parametru, to świetnie, ale chcę wykluczyć ucznia, jeśli ma on termin ważności certyfikatu większy niż zakres, w którym jest to ten sam typ co certyfikat, który mieści się w zakresie - nie musi być w nim raport. Oto pierwsze zapytanie, które mam:Zapytanie SQL o datę wygaśnięcia mieszczącą się w zakresie, ale wykluczenie, jeśli mają inną instancję tego samego typu.

SELECT s.student_id, s.fname, s.address1, s.lname, s.zip, s.state, s.city, s.student_type 
      FROM students s, certifications c 
      WHERE (s.student_id = c.student_id) 
      AND s.status='A' 
      AND s.student_type != 'B' 
      AND s.student_type != 'D' 
      AND s.student_type != 'E' 
      AND s.student_type != 'W' 
      AND s.student_type != 'T' 
      AND s.student_type != 'I' 
      AND c.expiration >= CURDATE() AND c.expiration <= DATE_ADD(NOW(), INTERVAL 1 YEAR) 
      GROUP BY s.student_id 
      ORDER BY s.lname, s.fname 

Następnie sql że rzeczywiście dostać się informacje CERT oparte na poprzedniej instrukcji SQL:

SELECT c.cert_num, c.date, expiration, ct.name, ct.cert_type, c.cert_id, c.student_id 
       FROM certifications c, cert_type ct 
       WHERE student_id = '{$Row['student_id']}' 
       AND ct.cert_type = c.cert_type 
       ORDER BY ct.name ASC, expiration DESC 

Więc Podsumowując, problem, że biegnę do jest to, że studenci pojawią się, jeśli ich ważność wygaśnie za rok, a jeśli będą mieli inny certyfikat tego samego typu, który ma wygaśnięcie większe niż zakres. To nie dobrze.

Czy istnieje sposób sprawdzenia, aby upewnić się, że dany typ certyfikatu mieści się w zakresie dat, a jeśli tak, to upewnij się, że nie ma certyfikatu tego samego typu, który jest większy niż zakres? Nie obchodzi go, czy wymaga innego zapytania SQL.

Odpowiedz

1

Możliwe, że uporałem się z uproszczeniem problemu, ale czy nie można uzyskać maksymalnej daty wygaśnięcia dla każdej kombinacji uczeń/typ? na przykład

SELECT s.student_id, 
     s.fname, 
     s.address1, 
     s.lname, 
     s.zip, 
     s.state, 
     s.city, 
     s.student_type 
FROM Students s 
     INNER JOIN 
     ( SELECT c.student_ID, 
        c.Cert_Type, 
        MAX(Expiration) AS Expiration 
      FROM Certifications c 
      GROUP BY c.student_ID, c.Cert_Type 
     ) c 
      ON s.Student_ID = c.Student_ID 
WHERE s.Student_Type NOT IN ('B', 'D', 'E', 'W', 'T', 'I') 
AND  c.expiration >= CURDATE() AND c.expiration <= DATE_ADD(NOW(), INTERVAL 1 YEAR) 
GROUP BY s.student_id, s.fname, s.address1, s.lname, s.zip, s.state, s.city, s.student_type 
+0

To właśnie dla mnie zadziałało! Dziękuję bardzo GarethD! Niestety mój pierwotny post nie miał większego sensu, był pod koniec mojego dnia pracy. W każdym razie, dziękuję wszystkim, którzy odpowiedzieli, nauczyłem się całkiem sporo z twoich postów. Zdałem sobie również sprawę, że będę musiał przeczytać więcej o "złączeniach". –

1

Korzystanie podkwerenda:

SELECT s.student_id, s.fname, s.address1, s.lname, s.zip, s.state, s.city, s.student_type 
    FROM students s, certifications c 
    WHERE (s.student_id = c.student_id) 
    AND s.status='A' 
    AND s.student_type != 'B' 
    AND s.student_type != 'D' 
    AND s.student_type != 'E' 
    AND s.student_type != 'W' 
    AND s.student_type != 'T' 
    AND s.student_type != 'I' 
    AND c.expiration >= CURDATE() AND c.expiration <= DATE_ADD(NOW(), INTERVAL 1 YEAR) 
    AND NOT EXISTS (
     SELECT c_inner.id 
     FROM certifications c_inner 
     WHERE c.expiration > DATE_ADD(NOW(), INTERVAL 1 YEAR) 
     AND c.student_id = c_inner.student_id 
    ) 
    GROUP BY s.student_id 
    ORDER BY s.lname, s.fname 

myślę, że powinno być możliwe byłaby to do przyłączenia, które mogłyby dać lepsze wyniki.

0
SELECT s.student_id, s.fname, s.address1, s.lname, s.zip, s.state, s.city, s.student_type 
    FROM students s 
    JOIN certifications c ON c.student_id = s.student_id 
    LEFT JOIN certifications c2 ON c2.student_id = s.student_id 
AND c2.expiration > DATE_ADD(NOW(), INTERVAL 1 YEAR) 
    JOIN cert_type ct ON ct.cert_type=c.cert_type 
    WHERE (s.student_id = c.student_id) 
    AND s.status='A' 
    AND s.student_type != 'B' 
    AND s.student_type != 'D' 
    AND s.student_type != 'E' 
    AND s.student_type != 'W' 
    AND s.student_type != 'T' 
    AND s.student_type != 'I' 
    AND c.expiration >= CURDATE() AND c.expiration <= DATE_ADD(NOW(), INTERVAL 1 YEAR) 
    AND c2.student_id is null 
    ORDER BY s.lname, s.fname 
+0

Dodałem sprzężenie, aby wyciągnąć informacje z cert_type w jednym zapytaniu. –

Powiązane problemy