2012-10-29 5 views
6

Ecco il problema in modalità dettagliata. Ho istanze di certificazioni su una tabella di certificazione e tutte hanno un tipo e uno studente ad esse associato. Ecco cosa voglio che accada, voglio tirare tutti i certificati con una scadenza che rientra in un intervallo di date (ORA a 1 anno). Se si qualificano per quel parametro, ottimo ma poi voglio escludere lo studente se hanno una scadenza di cert che è maggiore dell'intervallo quando è dello stesso tipo del certificato che rientra nell'intervallo - non è necessario che sia in il rapporto. Ecco la prima domanda che ho:Query SQL per includere una data di scadenza che rientra in un intervallo, ma escludere se hanno un'altra istanza dello stesso tipo

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 

Poi l'SQL che effettivamente ottenere di Info del CERT in base alla precedente dichiarazione di 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 

Quindi, per riassumere, il problema che sto correndo in è che gli studenti si presentano se la scadenza del certificato cade tra un anno e se hanno un altro certificato dello stesso tipo che ha una scadenza maggiore dell'intervallo. Non va bene.

Esiste un modo per verificare che un determinato tipo di certificato rientri nell'intervallo di date e, in caso affermativo, assicurarsi che non abbiano un certificato dello stesso tipo superiore all'intervallo? Non importa se ci vuole un'altra query sql.

risposta

1

È possibile che io abbia finito di semplificare il problema, ma non è possibile ottenere la data di scadenza massima per qualsiasi combinazione studente/tipo? per esempio.

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

Questo è quello che ha funzionato per me! Grazie mille GarethD! Scusate il mio post originale non ha molto senso, era alla fine della mia giornata di lavoro. Comunque, grazie a tutte le risposte, ho imparato un bel po 'dai tuoi post. Ho anche capito che dovrò leggere di più su "join". –

1

Utilizzando una sottoquery:

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 

penso che dovrebbe essere possibile refactoring questo in un join, che potrebbe dare prestazioni migliori.

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

Ho aggiunto un join per estrarre le informazioni da cert_type in una query. –

Problemi correlati