2012-07-04 13 views
8

Ho bisogno di eseguire un relativamente facile da spiegare ma (date le mie competenze un po 'limitate) difficile scrivere query SQL.Query astuta di SQL che coinvolge valori consecutivi

Supponiamo di avere un tavolo simile a questo:

exam_no | name | surname | result | date 
---------+------+---------+--------+------------ 
1  | John | Doe  | PASS | 2012-01-01 
1  | Ryan | Smith | FAIL | 2012-01-02 <-- 
1  | Ann | Evans | PASS | 2012-01-03 
1  | Mary | Lee  | FAIL | 2012-01-04 
...  | ... | ...  | ... | ... 
2  | John | Doe  | FAIL | 2012-02-01 <-- 
2  | Ryan | Smith | FAIL | 2012-02-02 
2  | Ann | Evans | FAIL | 2012-02-03 
2  | Mary | Lee  | PASS | 2012-02-04 
...  | ... | ...  | ... | ... 
3  | John | Doe  | FAIL | 2012-03-01 
3  | Ryan | Smith | FAIL | 2012-03-02 
3  | Ann | Evans | PASS | 2012-03-03 
3  | Mary | Lee  | FAIL | 2012-03-04 <-- 

noti che exam_no e date non sono necessariamente correlati, come ci si potrebbe aspettare dal tipo di esempio che ho scelto.

Ora, la domanda che ho bisogno di fare è la seguente:

  • Dalle ultime esame (exam_no = 3) trovare tutti gli studenti che non sono riusciti (John Doe, Ryan Smith e Mary Lee).
  • Per ciascuno di questi studenti, trovare la data del primo lotto di esami consecutivi in ​​mancanza. Un altro modo per dirlo sarebbe: per ognuno di questi studenti, trova la data del primo esame fallito che viene dopo l'ultimo esame di passaggio. (Guarda le frecce sul tavolo).

La tabella risultante dovrebbe essere qualcosa di simile:

name | surname | date_since_failing 
------+---------+-------------------- 
John | Doe  | 2012-02-01 
Ryan | Smith | 2012-01-02 
Mary | Lee  | 2012-03-04 

Come posso eseguire una query?

Grazie per il vostro tempo.

+0

Altri lettori: notare che lo ha taggato "MySQL" –

+0

Pensa di poter partecipare alla stessa tabella su result = "FAIL" e selezionare da esso quella con la data più alta. Che cosa hai provato? – Jocke

+0

Cosa intendi con "* l'ultimo esame *"? L'esame che ha l'ultima data? – eggyal

risposta

4

Si può approfittare del fatto che se qualcuno superato l'esame più recente, quindi non hanno fallito eventuali esami in quanto il loro più recente passaggio: quindi il problema si riduce a trovare il primo esame non è riuscita in quanto il più recente passaggio:

SELECT name, surname, MIN(date) date_since_fail 
FROM  results NATURAL LEFT JOIN (
    SELECT name, surname, MAX(date) lastpass 
    FROM  results 
    WHERE result = 'PASS' 
    GROUP BY name, surname 
) t 
WHERE result = 'FAIL' AND date > IFNULL(lastpass,0) 
GROUP BY name, surname 

vedi sul sqlfiddle.

+0

Questo è esattamente. Non posso credere quanto sia conciso e semplice da capire. Sono riuscito ad adattarlo al mio vero problema con il minimo sforzo. Grazie mille. – Gabriel

0

dovrei usare una sottoquery che un download ultima superato l'esame, somthing come:

SET @query_exam_no = 3; 
SELECT 
name, 
surname, 
MIN(IF(date > last_passed_exam, date, NULL)) AS date_failing_since 
FROM 
exam_results 
LEFT JOIN (
    SELECT 
    name, 
    surname, 
    MAX(date) AS last_passed_exam 
    FROM exam_results 
    WHERE result = 'PASS' 
    GROUP BY name, surname 
) AS last_passed_exams USING (name, surname) 
HAVING 
MAX(IF(exam_no = @query_exam_no, result, NULL)) = 'FAIL' 
GROUP BY name, surname 
0

Questo è sufficiente:

select t.name, 
     t.surname, 
     t.date as 'date_since_failing' 
from tablename t 
inner join 
(
    select name, 
      surname, 
      max(exam_no) as exam_no 
    from tablename 
    group by name, surname 
    having min(result) = 'FAIL' 
) aux on t.name = aux.name and t.surname = aux.surname and t.exam_no = aux.exam_no 
0

La condizione che stai chiedendo è un bene per niente che puoi fare senza di esso. Ecco l'esempio funzionante.

select 
    e.name, 
    e.sur_name, 
    min(e.date) as `LastFailed` 
from exams as e 
where e.result = 'Fail' 
group by e.name 
    order by e.name 

Questo produce questo risultato

name   sur_name LastFailed 
Ann   Evans  2012-02-03 
John  Doe   2012-02-01 
Mary  Lee   2012-01-04 
Ryan  Smith  2012-01-02 
+0

Questo non è il risultato che sto cercando. Le date dovrebbero essere quelle che appaiono nella tabella dei risultati nella mia domanda. Quello che sto cercando è la data del primo esame fallito nell'ultimo batch di esami consecutivi non riusciti per ciascuno di questi studenti. – Gabriel

+0

No, mi dispiace. I risultati che sto cercando sono esattamente quelli che ho scritto originariamente nella mia domanda.Per favore non modificare la mia domanda per adattarla ai risultati, è davvero irrispettoso. – Gabriel

Problemi correlati