2012-07-04 27 views
8

Necesito realizar una consulta SQL relativamente fácil de explicar pero (dada mi capacidad limitada) difícil de escribir.Consulta compleja de SQL que implica valores consecutivos

Asumamos que tenemos una tabla similar a ésta:

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 <-- 

Tenga en cuenta que exam_no y date no están necesariamente relacionados como uno podría esperar de la clase de ejemplo que elegí.

Ahora, la consulta que tengo que hacer es la siguiente:

  • Desde el último examen (exam_no = 3) una lista de los estudiantes que han fracasado (John Doe, Ryan Smith y Mary Lee).
  • Para cada uno de estos estudiantes, encuentre la fecha del primero del lote de exámenes consecutivos con errores. Otra forma de expresarlo sería: para cada uno de estos estudiantes, encuentre la fecha del primer examen reprobado que se presente después de su último examen de aprobación. (Mira las flechas en la tabla).

El cuadro resultante debe ser algo como esto:

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

¿Cómo puedo realizar una consulta de este tipo?

Gracias por su tiempo.

+0

Otros lectores: nota que lo etiquetó 'MySQL' –

+0

Creo que puede unirse en la misma tabla en result = 'FAIL' y seleccione de allí el que tenga la fecha más alta. ¿Qué has intentado? – Jocke

+0

¿Qué quiere decir con "* el último examen *"? El examen que tiene la última fecha? – eggyal

Respuesta

4

Puede aprovechar el hecho de que si alguien pasó el examen más reciente, entonces ellos no han fallado los exámenes, ya que su pase más reciente: por lo tanto, el problema se reduce a encontrar el primer examen no aprobado desde el paso más reciente:

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 

verlo en sqlfiddle.

+0

Esto es exactamente eso. No puedo creer lo conciso y simple de entender que es. Logré adaptarlo a mi problema real con el mínimo esfuerzo. Muchas gracias. – Gabriel

0

debo utilizar una subconsulta que buscar la última pasaron el examen, algo como:

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

Esto es suficiente:

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 condición que está pidiendo es bueno para nada que puedas hacer sin ella. Aquí está el ejemplo de trabajo.

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 

Esto produce este resultado

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

Este no es el resultado que estoy buscando. Las fechas deben ser las que aparecen en la tabla de resultados en mi pregunta. Lo que estoy buscando es la fecha del primer examen fallido en el último lote de exámenes fallidos consecutivos para cada uno de estos estudiantes. – Gabriel

+0

No, lo siento. Los resultados que estoy buscando son exactamente los que originalmente escribí en mi pregunta.Por favor, no edite mi pregunta para que se ajuste a sus resultados, es realmente irrespetuoso. – Gabriel

Cuestiones relacionadas