2012-02-04 34 views
14

Supongamos que tengo los siguientes dos tablas:LEFT JOIN en Valor máximo

STUDENT 
studentid lastname firstname 
1   Smith  John 
2   Drew  Nancy 

STUDENT_STORY 
studentid dateline storyid status 
1   1328313600 10  2 
1   1328313601 9   1 
2   1328313602 14  2 
2   1328313603 12  1 

Ahora, necesito una consulta SQL que seleccione cada estudiante, junto con la historia más reciente para ese estudiante en la tabla de historia de los estudiantes.

Estoy tratando esto:

SELECT s.*, ss.* 
FROM student AS s 
LEFT JOIN (
    SELECT * 
    FROM student_story 
    WHERE student_story.studentid = s.studentid 
    ORDER BY dateline DESC LIMIT 1 
) AS ss ON (ss.studentid = s.studentid) 

Sin embargo, esta consulta no funciona. Se queja de que s.studentid es un campo desconocido en la cláusula where de la consulta secundaria.

Por favor sugiera cómo puedo lograr lo que estoy tratando de hacer.

Gracias.

Respuesta

17

intentar algo como esto:

SELECT 
    s.*, 
    ss.* 
FROM 
    student AS s 
LEFT JOIN 
    student_story AS ss 
ON (ss.studentid = s.studentid) 
WHERE ss.dateline = (
    SELECT 
    MAX(dateline) 
    FROM 
    student_story AS ss2 
    WHERE 
    ss2.studentid = s.studentid 
) 
+1

Ahora, cuando pienso en ello, esto podría devolver el mismo estudiante dos veces si había múltiples entradas con la misma marca de tiempo, así que probablemente no uses esto. – Detheroc

+0

Esto nunca debería ser el caso a menos que algo esté muy mal. ¿Cómo arreglo esta consulta para que no devuelva el mismo estudiante dos veces si hay varias entradas con la misma marca de tiempo? – akanevsky

+0

Si también se garantiza que las ID en la tabla student_story van a aumentar con el tiempo, podría seleccionar y comparar la ID máxima. Sin embargo, este no parece ser el caso en su ejemplo, por lo que el problema probablemente sea bastante complicado. ¿La solución de Vyktor no funcionó? Parece bastante razonable. – Detheroc

1

Esto se unen debería hacerlo:

SELECT s.*, ss.* 
FROM student_story AS ss 
LEFT JOIN student AS s 
    ON student_story.studentid = s.userid 
GROUP BY ss.studentid 

GROUP BY debe tomar la última fila, por lo que la última historia = última fila, si no va a tratar de trabajar :

GROUP BY ss.studentid, ss.dateline DESC 

no estoy seguro de ello, por favor, comentar con el resultado de

+0

No. "el servidor es libre de elegir cualquier valor de esta columna no agregada" https://dev.mysql.com/doc/refman/5.7/en/group-by-modifiers.html –

4
SELECT s.*, ss.* 
FROM student AS s 
LEFT JOIN (

SELECT * FROM student_story  
ORDER BY dateline DESC LIMIT 1 
) 
AS ss ON (ss.studentid = s.studentid) 
+0

Lo aprendí de todas las respuestas proporcionadas pero tuyo me dio un mejor trabajo hecho. –

+0

Esto no funciona porque la selección secundaria solo devuelve un resultado para todos los alumnos que no se pueden unir para todos excepto para el último student_story más reciente. – Roben

0

Usted tendrá que añadir un auto y la identificación única para cada fila en la tabla student_story.

y luego distinguirá entre ellos. (Asumir studentstory.new_id)

select s.*, ss.* 
from student s 
left join student_story ss on ss.studentid = s.userid 
where ss.new_id = (select ss.new_id from student s 
    group by dateline 
    order by dateline desc 
    limit 1 
) 
1
SELECT 
    s.sale_id, 
    s.created_at, 
    p.created_at, 
    DATEDIFF(p.created_at, s.created_at) AS days 
FROM 
    pos_sales s 
     LEFT JOIN 
    pos_payments p ON p.sale_id = s.sale_id 
     AND 
    p.created_at = (SELECT 
      MAX(p2.created_at) 
     FROM 
      pos_payments p2 
     WHERE 
      p2.sale_id = p.sale_id) 
0

Otro enfoque es hacer una LEFT JOIN con una condición NOT EXISTS(). Dependiendo de la situación, esto puede dar un poco más de flexibilidad; Sin embargo, también se muestran los resultados duplicados si hay dos entradas con el mismo dateline por estudiante:

SELECT s.*, ss.* 
FROM student AS s 
LEFT JOIN student_story AS ss ON ss.studentid = s.studentid AND NOT EXISTS 
    (SELECT * FROM student_story AS ss2 
    WHERE ss2.studentid = ss.studentid AND ss2.dateline > ss.dateline)