Unión a la izquierda de TSQL y solo la última fila desde la derecha


Estoy escribiendo sql query para obtener post y solo el último comentario de este post(si existe). Pero no puedo encontrar una manera de limitar solo 1 fila para la columna derecha en unión izquierda.

Aquí está una muestra de esta consulta.

SELECT post.id, post.title,comment.id,comment.message
from post
left outer join comment
on post.id=comment.post_id

Si la publicación tiene 3 comentarios, obtengo 3 filas con esta publicación, pero solo quiero 1 fila con el último comentario(ordenado por fecha).

¿Puede alguien ayudarme con esta consulta?

Author: barbarian, 2010-02-17

6 answers

SELECT  post.id, post.title, comment.id, comment.message
FROM    post
OUTER APPLY
        (
        SELECT  TOP 1 *
        FROM    comment с
        WHERE   c.post_id = post.id
        ORDER BY
                date DESC
        ) comment

O

SELECT  *
FROM    (
        SELECT  post.id, post.title, comment.id, comment.message,
                ROW_NUMBER() OVER (PARTITION BY post.id ORDER BY comment.date DESC) AS rn
        FROM    post
        LEFT JOIN
                comment
        ON      comment.post_id = post.id
        ) q
WHERE   rn = 1

El primero es más eficiente para pocos posts con muchos comentarios en cada uno; el segundo es más eficiente para muchos posts con pocos comentarios en cada uno.

 51
Author: Quassnoi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-01-06 17:32:28

[1]} Subconsulta:

SELECT p.id, p.title, c.id, c.message
FROM post p
LEFT join comment c
ON c.post_id = p.id AND c.id = 
                 (SELECT MAX(c.id) FROM comment c2 WHERE c2.post_id = p.id)
 14
Author: AGoodDisplayName,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-13 16:00:01

Querrás unirte a una sub-consulta que devuelva el último comentario de la publicación. Por ejemplo:

select post.id, post.title. lastpostid, lastcommentmessage
from post
inner join
(
    select post.id as lastpostid, max(comment.id) as lastcommentmessage
    from post
    inner join comment on commment.post_id = post.id
    group by post.id
) lastcomment
    on lastpostid = post.id
 3
Author: Paul Williams,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-02-17 14:49:26

Un par de opciones....

Una forma es hacer el JOIN on:

SELECT TOP 1 comment.message FROM comment ORDER BY comment.id DESC

(nota Estoy asumiendo que comment.id es un campo de identidad)

 1
Author: Ian Jacobs,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-02-17 14:50:37

¿Qué versión de SQL Server? Si tiene la función Row_Number() disponible, puede ordenar sus comentarios por lo que "first" signifique para usted y luego simplemente agregue una cláusula "where RN=1". No tengo un ejemplo práctico o la sintaxis correcta en la parte superior de mi cabeza, pero tengo toneladas de consultas que hacen exactamente esto. Otras publicaciones están todas en las 1,000 de maneras en que podrías hacer esto.

Yo diría que el perfil y ver cuál funciona mejor para usted.

 1
Author: No Refunds No Returns,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-02-17 14:54:24

No dijiste el nombre específico de tu campo de fecha, así que rellené con [DateCreated]. Esto es esencialmente lo mismo que el post anterior de AGoodDisplayName, pero usando el campo date en lugar de confiar en el orden de la columna ID.

SELECT post.id, post.title, comment.id, comment.message
FROM post p
LEFT OUTER JOIN comment
ON comment.id = (
    SELECT TOP 1 id
    FROM comment
    WHERE p.id = post_id
    ORDER BY [DateCreated] ASC
)
 0
Author: Andy Raddatz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-12 20:37:55