Consulta MYSQL – Obtener el último comentario relacionado con la publicación

Estoy tratando de get los últimos 1 o 2 comentarios relacionados con cada publicación que descargo, un poco como instagram, ya que muestran los últimos 3 comentarios para cada publicación, hasta ahora estoy recibiendo las publicaciones y lo que me gusta count.

Ahora todo lo que tengo que hacer es descubrir cómo get los últimos comentarios, no estoy muy seguro de cómo abordarlo y es por eso que espero que alguien con mucha más experiencia pueda ayudarme.

Esta es mi consulta actual:

(SELECT P.uuid, P.caption, P.imageHeight, P.path, P.date, U.id, U.fullname, U.coverImage, U.bio, U.username, U.profileImage, coalesce(Activity.LikeCNT,0), Activity.CurrentUserLiked FROM USERS AS U INNER JOIN Posts AS P ON P.id = U.id LEFT JOIN (SELECT COUNT(DISTINCT Activity.uuidPost) LikeCNT, Activity.uuidPost, Activity.id, sum(CASE WHEN Activity.id = $id then 1 else 0 end) as CurrentUserLiked FROM Activity Activity WHERE type = 'like' GROUP BY Activity.uuidPost) Activity ON Activity.uuidPost = P.uuid AND Activity.id = U.id WHERE U.id = $id) UNION (SELECT P.uuid, P.caption, P.imageHeight, P.path, P.date, U.id, U.fullname, U.coverImage, U.bio, U.username, U.profileImage, coalesce(Activity.LikeCNT,0), Activity.CurrentUserLiked FROM Activity AS A INNER JOIN USERS AS U ON A.IdOtherUser=U.id INNER JOIN Posts AS P ON P.id = U.id LEFT JOIN (SELECT COUNT(DISTINCT Activity.uuidPost) LikeCNT, Activity.uuidPost, Activity.id, sum(CASE WHEN Activity.id = $id then 1 else 0 end) as CurrentUserLiked FROM Activity Activity WHERE type = 'like' GROUP BY Activity.uuidPost) Activity ON Activity.uuidPost = P.uuid AND Activity.id = U.id WHERE A.id = $id) ORDER BY date DESC LIMIT 0, 5 

Básicamente, los comentarios se almacenan en la misma tabla que los "Me gusta".

Entonces la tabla es Activity , luego tengo un comment columna que almacena el text del comentario, y luego el "tipo" es igual a "comentario".

¡Posiblemente no muy bien explicado, pero estoy dispuesto a intentar y dar tantos detalles como sea posible!

¡Si alguien puede ayudar, es muy apreciado!

ACTUALIZAR

En esta consulta dada por https://stackoverflow.com/users/1016435/xqbert , estoy recibiendo este error:

Mezcla ilegal de intercalaciones (utf8_general_ci, IMPLICIT) y (utf8_unicode_ci, IMPLICIT) para la operación '='

 SELECT Posts.id, Posts.uuid, Posts.caption, Posts.path, Posts.date, USERS.id, USERS.username, USERS.fullname, USERS.profileImage, coalesce(A.LikeCNT,0), com.comment FROM Posts INNER JOIN USERS ON Posts.id = 145 AND USERS.id = 145 LEFT JOIN (SELECT COUNT(A.uuidPost) LikeCNT, A.UUIDPost FROM Activity A WHERE type = 'like' GROUP BY A.UUIDPOST) A on A.UUIDPost=Posts.uuid LEFT JOIN (SELECT comment, UUIDPOST, @row_num := IF(@prev_value=UUIDPOST,@row_num+1,1) as row_number,@prev_value := UUIDPOST FROM Activity CROSS JOIN (SELECT @row_num := 1) x CROSS JOIN (SELECT @prev_value := '') y WHERE type = 'comment' ORDER BY UUIDPOST, date DESC) Com ON Com.UUIIDPOSt = Posts.UUID AND row_number <= 2 ORDER BY date DESC LIMIT 0, 5 

Última edición

Estructuras de tabla:

Publicaciones

  ---------------------------------------------------------- | id | int(11) | | not null | | uuid | varchar(100) | utf8_unicode_ci | not null | | imageLink | varchar(500) | utf8_unicode_ci | not null | | date | timestamp | | not null | ---------------------------------------------------------- 

USUARIOS

  ------------------------------------------------------------- | id | int(11) | | not null | | username | varchar(100) | utf8_unicode_ci | not null | | profileImage | varchar(500) | utf8_unicode_ci | not null | | date | timestamp | | not null | ------------------------------------------------------------- 

Actividad

  ---------------------------------------------------------- | id | int(11) | | not null | | uuid | varchar(100) | utf8_unicode_ci | not null | | uuidPost | varchar(100) | utf8_unicode_ci | not null | | type | varchar(50) | utf8_unicode_ci | not null | | commentText | varchar(500) | utf8_unicode_ci | not null | | date | timestamp | | not null | ---------------------------------------------------------- 

Esos son algunos ejemplos, en la tabla "Actividad" en este caso "tipo" siempre será igual a "comentario".

Resumen de todo y deseo resultado:

Cuando consulto las publicaciones de los usuarios, me gustaría poder acceder a la tabla de "Actividad" y get los últimos 2 comentarios para cada publicación que tenga. Tal vez no haya comentarios, así que obviamente devolvería 0, tal vez podría haber 100 comentarios para esa publicación. Pero solo quiero get los últimos / más recientes 2 comentarios.

Un ejemplo podría ser ver cómo lo hace Instagram. Para cada publicación, muestra los comentarios más recientes 1, 2 o 3 ….

¡Espero que esto ayude!

Enlace violín

Este post de error

Mezcla ilegal de intercalaciones (utf8_general_ci, IMPLICIT) y (utf8_unicode_ci, IMPLICIT) para la operación '='

generalmente se debe a la definición de sus columnas y tablas. Por lo general, significa que en ambos lados de un signo igual hay diferentes intercalaciones. Lo que debe hacer es elegir uno e include esa decisión en su consulta.

El problema de la intercalación aquí fue en CROSS JOIN de @prev_value, que necesitaba una intercalación explícita para ser utilizada.

También modifiqué ligeramente la lógica "row_number" en una sola combinación cruzada y moví la lógica if a los extremos de la list de selección.

Algunos datos de muestra se muestran a continuación. Se necesitan datos de muestra para probar las consultas con. Cualquiera que intente responder su pregunta con ejemplos de trabajo necesitará datos. La razón por la que lo incluyo aquí es doble.

  1. para que entiendas cualquier resultado que presente
  2. para que en el futuro, cuando haga otra pregunta relacionada con SQL, comprenda la importancia de suministrar datos. No solo es más conveniente para nosotros que hagas esto. Si el asker proporciona los datos de la muestra, el asker ya lo entenderá: no será una invención de un extraño que haya dedicado parte de su time a ayudar.

Data de muestra

Tenga en count que faltan algunas columnas en las tablas, solo se han incluido las columnas especificadas en los detalles de la tabla.

Esta muestra de datos tiene 5 comentarios en una sola publicación (no se registran me gusta)

 CREATE TABLE Posts ( `id` int, `uuid` varchar(7) collate utf8_unicode_ci, `imageLink` varchar(9) collate utf8_unicode_ci, `date` datetime ); INSERT INTO Posts(`id`, `uuid`, `imageLink`, `date`) VALUES (145, 'abcdefg', 'blah blah', '2016-10-10 00:00:00') ; CREATE TABLE USERS ( `id` int, `username` varchar(15) collate utf8_unicode_ci, `profileImage` varchar(12) collate utf8_unicode_ci, `date` datetime ) ; INSERT INTO USERS(`id`, `username`, `profileImage`, `date`) VALUES (145, 'used_by_already', 'blah de blah', '2014-01-03 00:00:00') ; CREATE TABLE Activity ( `id` int, `uuid` varchar(4) collate utf8_unicode_ci, `uuidPost` varchar(7) collate utf8_unicode_ci, `type` varchar(40) collate utf8_unicode_ci, `commentText` varchar(11) collate utf8_unicode_ci, `date` datetime ) ; INSERT INTO Activity (`id`, `uuid`, `uuidPost`, `type`, `commentText`, `date`) VALUES (345, 'a100', 'abcdefg', 'comment', 'lah lha ha', '2016-07-05 00:00:00'), (456, 'a101', 'abcdefg', 'comment', 'lah lah lah', '2016-07-06 00:00:00'), (567, 'a102', 'abcdefg', 'comment', 'lha lha ha', '2016-07-07 00:00:00'), (678, 'a103', 'abcdefg', 'comment', 'ha lah lah', '2016-07-08 00:00:00'), (789, 'a104', 'abcdefg', 'comment', 'hla lah lah', '2016-07-09 00:00:00') ; 

[Comportamiento estándar de SQL: 2 filas por consulta de publicación]

Esta fue mi consulta inicial, con algunas correcciones. Cambié el order de las columnas de la list de selección para que pueda ver algunos datos relacionados con los comentarios fácilmente cuando presento los resultados. Estudie los resultados que se proporcionan para que pueda entender lo que hará la consulta. Las columnas precedidas por # no existen en los datos de muestra con los que estoy trabajando por razones que ya he señalado.

 SELECT Posts.id , Posts.uuid , rcom.uuidPost , rcom.commentText , rcom.`date` commentDate #, Posts.caption #, Posts.path , Posts.`date` , USERS.id , USERS.username #, USERS.fullname , USERS.profileImage , COALESCE(A.LikeCNT, 0) num_likes FROM Posts INNER JOIN USERS ON Posts.id = 145 AND USERS.id = 145 LEFT JOIN ( SELECT COUNT(A.uuidPost) LikeCNT , A.UUIDPost FROM Activity A WHERE type = 'like' GROUP BY A.UUIDPOST ) A ON A.UUIDPost = Posts.uuid LEFT JOIN ( SELECT @row_num := IF(@prev_value=UUIDPOST,@row_num+1,1) as row_number , commentText , uuidPost , `date` , @prev_value := UUIDPOST FROM Activity CROSS JOIN ( SELECT @row_num := 1, @prev_value := '' collate utf8_unicode_ci ) xy WHERE type = 'comment' ORDER BY uuidPost , `date` DESC ) rcom ON rcom.uuidPost = Posts.UUID AND rcom.row_number <= 2 ORDER BY posts.`date` DESC ; 

Vea una demostración de esta consulta en SQLFiddle

Resultados :

 | id | uuid | uuidPost | commentText | date | date | id | username | profileImage | num_likes | |-----|---------|----------|-------------|------------------------|---------------------------|-----|-----------------|--------------|-----------| | 145 | abcdefg | abcdefg | hla lah lah | July, 09 2016 00:00:00 | October, 10 2016 00:00:00 | 145 | used_by_already | blah de blah | 0 | | 145 | abcdefg | abcdefg | ha lah lah | July, 08 2016 00:00:00 | October, 10 2016 00:00:00 | 145 | used_by_already | blah de blah | 0 | 

Hay 2 FILAS, como se esperaba. Una fila para el comentario más reciente y otra fila para el siguiente comentario más reciente. Este es un comportamiento normal para SQL y hasta que se agregue un comentario en esta respuesta, los lectores de la pregunta asumirían que este comportamiento normal sería aceptable.

La pregunta carece de un "resultado esperado" claramente articulado.


[Opción 1: una fila por consulta de publicación, con HASTA 2 comentarios, columnas agregadas]

En un comentario a continuación, se reveló que no deseaba 2 filas por publicación y esta sería una solución fácil. Bueno, es fácil, PERO hay opciones y las opciones son dictadas por el usuario en forma de requisitos. SI la pregunta tuviera un "resultado esperado", sabríamos qué opción elegir. Sin embargo, aquí hay una opción

 SELECT Posts.id , Posts.uuid , max(case when rcom.row_number = 1 then rcom.commentText end) Comment_one , max(case when rcom.row_number = 2 then rcom.commentText end) Comment_two #, Posts.caption #, Posts.path , Posts.`date` , USERS.id , USERS.username #, USERS.fullname , USERS.profileImage , COALESCE(A.LikeCNT, 0) num_likes FROM Posts INNER JOIN USERS ON Posts.id = 145 AND USERS.id = 145 LEFT JOIN ( SELECT COUNT(A.uuidPost) LikeCNT , A.UUIDPost FROM Activity A WHERE type = 'like' GROUP BY A.UUIDPOST ) A ON A.UUIDPost = Posts.uuid LEFT JOIN ( SELECT @row_num := IF(@prev_value=UUIDPOST,@row_num+1,1) as row_number , commentText , uuidPost , `date` , @prev_value := UUIDPOST FROM Activity CROSS JOIN ( SELECT @row_num := 1, @prev_value := '' collate utf8_unicode_ci ) xy WHERE type = 'comment' ORDER BY uuidPost , `date` DESC ) rcom ON rcom.uuidPost = Posts.UUID AND rcom.row_number <= 2 GROUP BY Posts.id , Posts.uuid #, Posts.caption #, Posts.path , Posts.`date` , USERS.id , USERS.username #, USERS.fullname , USERS.profileImage , COALESCE(A.LikeCNT, 0) ORDER BY posts.`date` DESC ; 

Vea la segunda consulta trabajando en SQLFiddle

Resultados de la consulta 2 :

 | id | uuid | Comment_one | Comment_two | date | id | username | profileImage | num_likes | |-----|---------|-------------|-------------|---------------------------|-----|-----------------|--------------|-----------| | 145 | abcdefg | hla lah lah | ha lah lah | October, 10 2016 00:00:00 | 145 | used_by_already | blah de blah | 0 | 

** Opción 2, concatenar los comentarios más recientes en una sola list separada por comas **

 SELECT Posts.id , Posts.uuid , group_concat(rcom.commentText) Comments_two_concatenated #, Posts.caption #, Posts.path , Posts.`date` , USERS.id , USERS.username #, USERS.fullname , USERS.profileImage , COALESCE(A.LikeCNT, 0) num_likes FROM Posts INNER JOIN USERS ON Posts.id = 145 AND USERS.id = 145 LEFT JOIN ( SELECT COUNT(A.uuidPost) LikeCNT , A.UUIDPost FROM Activity A WHERE type = 'like' GROUP BY A.UUIDPOST ) A ON A.UUIDPost = Posts.uuid LEFT JOIN ( SELECT @row_num := IF(@prev_value=UUIDPOST,@row_num+1,1) as row_number , commentText , uuidPost , `date` , @prev_value := UUIDPOST FROM Activity CROSS JOIN ( SELECT @row_num := 1, @prev_value := '' collate utf8_unicode_ci ) xy WHERE type = 'comment' ORDER BY uuidPost , `date` DESC ) rcom ON rcom.uuidPost = Posts.UUID AND rcom.row_number <= 2 GROUP BY Posts.id , Posts.uuid #, Posts.caption #, Posts.path , Posts.`date` , USERS.id , USERS.username #, USERS.fullname , USERS.profileImage , COALESCE(A.LikeCNT, 0) ORDER BY posts.`date` DESC 

Vea esta tercera consulta trabajando en SQLFiddle

Resultados de la consulta 3 :

 | id | uuid | Comments_two_concatenated | date | id | username | profileImage | num_likes | |-----|---------|---------------------------|---------------------------|-----|-----------------|--------------|-----------| | 145 | abcdefg | hla lah lah,ha lah lah | October, 10 2016 00:00:00 | 145 | used_by_already | blah de blah | 0 | 

** Resumen **

He presentado 3 consultas, cada una muestra solo los 2 comentarios más recientes, pero cada consulta lo hace de forma diferente. La primera consulta (comportamiento pnetworkingeterminado) mostrará 2 filas para cada publicación. La opción 2 agrega una columna pero elimina la segunda fila. La opción 3 concatena los 2 comentarios más recientes.

Tenga en count que:

  • La pregunta carece de definiciones de tabla que cubran todas las columnas
  • La pregunta carece de datos de muestra, lo que hace que sea más difícil para usted entender los resultados presentados aquí, pero también es más difícil para nosotros preparar soluciones.
  • La pregunta también carece de un "resultado esperado" definitivo (el resultado deseado) y esto ha llevado a una mayor complejidad en la respuesta

Espero que la información adicional proporcionada sea de alguna utilidad, y que ahora también sepas que es normal que SQL presente los datos como filas múltiples. Si no desea ese comportamiento normal, sea específico sobre lo que realmente desea en su pregunta.


Posdata. Para include otra subconsulta para "seguir", puede usar una subconsulta similar a la que ya tiene. Se puede agregar antes o después de esa subconsulta. También puede verlo en uso en sqlfiddle aquí

 LEFT JOIN ( SELECT COUNT(*) FollowCNT , IdOtherUser FROM Activity WHERE type = 'Follow' GROUP BY IdOtherUser ) F ON USERS.id = F.IdOtherUser 

Si bien agregar otra subconsulta puede resolver su deseo de get más información, la consulta general puede ser más lenta en proporción al crecimiento de sus datos. Una vez que haya establecido la funcionalidad que realmente necesita, puede valer la pena considerar qué índices necesita en esas tablas. (Creo que se le aconsejaría que solicite ese asesoramiento por separado, y si se asegura de include 1. el DDL completo de sus tablas y 2. un plan de explicación de la consulta).

Estoy un poco perdido en su consulta, pero si desea download datos para varias publicaciones a la vez, no es una buena idea include datos de comentarios en la primera consulta ya que includeía todos los datos sobre la publicación y la publicación del usuario varias veces. . Debería ejecutar otra consulta que conectaría publicaciones con comentarios. Algo como:

 SELECT A.UUIDPost, C.username, C.profileImage, B.Comment, B.[DateField] FROM Posts A JOIN Activities B ON A.uuid = B.UUIDPost JOIN Users C ON B.[UserId] = C.id 

y use esa información para mostrar sus comentarios con un nombre de usuario, nombre, image, etc.

Para get solo 3 comentarios por publicación, puede consultar esta publicación:

Seleccione los 3 mejores valores de cada grupo en una tabla con SQL

si está seguro de que no habrá filas duplicadas en la tabla de comentarios o en esta publicación:

Cómo seleccionar los 3 mejores valores de cada grupo en una tabla con SQL que tienen duplicates

si no está seguro de eso (aunque debido a DateField en la tabla, no debería ser posible).

NO TESTIFICADO: recomendaría armar un violín de SQL con algunos datos de muestra y la estructura de la tabla existente que muestra el problema; de esa manera podríamos jugar con las respuestas y asegurar la funcionalidad con su esquema.

Entonces usamos variables para simular una function de window (como row_number)

en este caso @Row_num y @prev_Value. @Row_number realiza un seguimiento de la fila actual para cada publicación (ya que una sola publicación podría tener muchos comentarios) y cuando se encuentra una nueva ID de publicación (UUIDPOST?), La variable row_num se restablece a 1. Cuando los loggings actuales UUIDPOST coinciden con variable @prev_Value, simplemente incrementamos la fila por 1.

Esta técnica nos permite asignar un número de fila basado en la order de date o ID de actividad descendiente. Como cada combinación cruzada solo da como resultado 1 logging, no hacemos que aparezcan loggings duplicates. Sin embargo, dado que luego limitamos por row_number <= 2, solo obtenemos los dos comentarios más recientes en nuestra unión izquierda recién agregada.

Esto supone que la relación de publicaciones con los usuarios es de Muchos a uno, lo que significa que una publicación solo puede tener 1 usuario.

Algo como esto: aunque no estoy seguro acerca de la unión final izquierda, necesito entender mejor la estructura de la tabla de actividades, por lo tanto, un comentario en contra de la pregunta original.

 SELECT Posts.id, Posts.uuid, Posts.caption, Posts.path, Posts.date, USERS.id, USERS.username, USERS.fullname, USERS.profileImage, coalesce(A.LikeCNT,0) com.comment FROM Posts INNER JOIN USERS ON Posts.id = 145 AND USERS.id = 145 LEFT JOIN (SELECT COUNT(A.uuidPost) LikeCNT, A.UUIDPost FROM Activity A WHERE type = 'like' GROUP BY A.UUIDPOST) A on A.UUIDPost=Posts.uuid --This join simulates row_Number() over (partition by PostID, order by activityID desc) (Nice article [here](http://preilly.me/2011/11/11/mysql-row_number/) several other examples exist on SO already. --Meaning.... Generate a row number for each activity from 1-X restarting at 1 for each new post but start numbering at the newest activityID) LEFT JOIN (SELECT comment, UUIDPOST, @row_num := IF(@prev_value=UUIDPOST,@row_num+1,1) as row_number,@prev_value := UUIDPOST FROM ACTIVITY CROSS JOIN (SELECT @row_num := 1) x CROSS JOIN (SELECT @prev_value := '') y WHERE type = 'comment' ORDER BY UUIDPOST, --Some date or ID desc) Com on Com.UUIIDPOSt = Posts.UUID and row_number < = 2 -- Now since we have a row_number restarting at 1 for each new post, simply return only the 1st two rows. ORDER BY date DESC LIMIT 0, 5 

tuvimos que poner el y row_number <= 2 en la unión misma. Si fue puesto en la cláusula where, perderías esas publicaciones sin ningún comentario que creo que aún deseas.

Además, probablemente deberíamos mirar el campo de "comentarios" para asegurarnos de que no esté en blanco o nulo, pero asegurémonos de que esto funcione primero.

Este tipo de comentario ha sido publicado muchas veces, y tratar de get el "último para cada uno" siempre parece ser un obstáculo y una pesadilla de unión / subconsulta para la mayoría.

Especialmente para una interfaz web, es mejor colocar una columna (o 2 o 3) en la tabla que es su tabla activa de "publicaciones" como Latest1, Latest2, Latest3.

Luego, a través de una inserción en su tabla de comentarios, tenga un disparador de inserción en su table para actualizar la publicación principal con la ID más reciente. Entonces siempre tienes esa ID en la table sin ningún sub-uniones. Ahora, como mencionó, es posible que desee tener los últimos 2 o 3 ID, luego agregue las 3 columnas de muestra y haga que su inserción se dispare a los detalles del comentario de la publicación, haga una actualización a la tabla de correos principal, algo así como

 update PrimaryPostTable set Latest3 = Latest2, Latest2 = Latest1, Latest1 = NewDetailCommentID where PostID = PostIDFromTheInsertedDetail 

Esto debería formalizarse en un disparador apropiado bajo MySQL, pero debería ser lo suficientemente fácil de implementar. Puede preparar la list con el último 1, y luego, a medida que se publiquen las nuevas publicaciones, automáticamente se colocarán las más recientes en sus posiciones 1 °, 2 °, 3 °. Finalmente su consulta podría simplificarse a algo así como

 Select P.PostID, P.TopicDescription, PD1.WhateverDetail as LatestDetail1, PD2.WhateverDetail as LatestDetail2, PD3.WhateverDetail as LatestDetail3 from Posts P LEFT JOIN PostDetail PD1 on P.Latest1 = PD1.PostDetailID LEFT JOIN PostDetail PD2 on P.Latest2 = PD2.PostDetailID LEFT JOIN PostDetail PD3 on P.Latest3 = PD3.PostDetailID where whateverCondition 

La desnormalización de datos normalmente NO es deseada. Sin embargo, en casos como este, es un gran simplificador para get estas "últimas" inputs en un tipo de consulta For-Each. Buena suerte.

Aquí hay una muestra completamente funcional en MySQL para que pueda ver las tablas y los resultados de las inserciones sql y el estampado automático a través del gatillo para actualizar la tabla principal de publicaciones. Luego, al consultar la tabla de publicaciones, puede ver cómo la más reciente se desplaza automáticamente a la primera, segunda y tercera position. Finalmente, una combinación que muestra cómo extraer todos los datos de cada "actividad de publicación"

 CREATE TABLE Posts ( id int, uuid varchar(7), imageLink varchar(9), `date` datetime, ActivityID1 int null, ActivityID2 int null, ActivityID3 int null, PRIMARY KEY (id) ); CREATE TABLE Activity ( id int, postid int, `type` varchar(40) collate utf8_unicode_ci, commentText varchar(20) collate utf8_unicode_ci, `date` datetime, PRIMARY KEY (id) ); DELIMITER // CREATE TRIGGER ActivityRecAdded AFTER INSERT ON Activity FOR EACH ROW BEGIN Update Posts set ActivityID3 = ActivityID2, ActivityID2 = ActivityID1, ActivityID1 = NEW.ID where ID = NEW.POSTID; END; // DELIMITER ; INSERT INTO Posts (id, uuid, imageLink, `date`) VALUES (123, 'test1', 'blah', '2016-10-26 00:00:00'); INSERT INTO Posts (id, uuid, imageLink, `date`) VALUES (125, 'test2', 'blah 2', '2016-10-26 00:00:00'); INSERT INTO Activity (id, postid, `type`, `commentText`, `date`) VALUES (789, 123, 'type1', 'any comment', '2016-10-26 00:00:00'), (821, 125, 'type2', 'another comment', '2016-10-26 00:00:00'), (824, 125, 'type3', 'third comment', '2016-10-27 00:00:00'), (912, 123, 'typeAB', 'comment', '2016-10-27 00:00:00'); -- See the results after the insert and the triggers. -- you will see that the post table has been updated with the -- most recent -- activity post ID=912 in position Posts.Activity1 -- activity post ID=789 in position Posts.Activity2 -- no value in position Posts.Activity3 select * from Posts; -- NOW, insert two more records for post ID = 123. -- you will see the shift of ActivityIDs adjusted INSERT INTO Activity (id, postid, `type`, `commentText`, `date`) VALUES (931, 123, 'type1', 'any comment', '2016-10-28 00:00:00'), (948, 123, 'newest', 'blah', '2016-10-29 00:00:00'); -- See the results after the insert and the triggers. -- you will see that the post table has been updated with the -- most recent -- activity post ID=948 in position Posts.Activity1 -- activity post ID=931 in position Posts.Activity2 -- activity post ID=912 in position Posts.Activity3 -- notice the FIRST activity post 789 is not there as -- anything AFTER the 4th entry, it got pushed away. select * from Posts; -- Finally, query the data to get the most recent 3 items for each post. select p.id, p.uuid, p.imageLink, p.`date`, A1.id NewestActivityPostID, A1.`type` NewestType, A1.`date` NewestDate, A2.id SecondActivityPostID, A2.`type` SecondType, A2.`date` SecondDate, A3.id ThirdActivityPostID, A3.`type` ThirdType, A3.`date` ThirdDate from Posts p left join Activity A1 on p.ActivityID1 = A1.ID left join Activity A2 on p.ActivityID2 = A2.ID left join Activity A3 on p.ActivityID3 = A3.ID; 

Puede crear una database de testing para no corromper la suya para ver este ejemplo.

Esto probablemente eliminará la mezcla ilegal de queueciones … Justo después de establecer la connection, realice esta consulta:

 SET NAMES utf8 COLLATE utf8_unicode_ci; 

Para la pregunta sobre los 'últimos 2', utilice la herramienta de command-line mysql y ejecute SHOW CREATE TABLE Posts y proporcione la salida. (Lo mismo para las otras tablas relevantes.) Phpmyadmin (y otras UI) tienen una forma de realizar la consulta sin llegar a una línea de command.

Puede llegar allí con una consulta bastante simple mediante el uso de subconsultas. Primero especifico el usuario en la cláusula where y me uno a las publicaciones porque me parece más lógico. Luego obtengo todos los "Me gusta" para una publicación con una sub consulta.

Ahora, en lugar de agrupar y limitar el tamaño del grupo, solo unimos los valores que queremos al limitar el recuento de dates después de la date que estamos viendo actualmente.

INNER JOIN Activity si solo quieres mostrar publicaciones con al less un comentario.

 SELECT u.id, u.username, u.fullname, u.profileImage, p.uuid, p.caption, p.path, p.date, (SELECT COUNT(*) FROM Activity v WHERE v.uuidPost = p.uuidPost AND v.type = 'like') likes, a.commentText, a.date FROM Users u INNER JOIN Posts p ON p.id = u.id LEFT JOIN Activity a ON a.uuid = p.uuid AND a.type = 'comment' AND 2 > ( SELECT COUNT(*) FROM Activity v WHERE v.uuid = p.uuid AND v.type = 'comment' AND v.date > a.date) WHERE u.id = 145 

Dicho esto, un networkingiseño probablemente sea mejor, también en cuanto a performance (la actividad pronto includeá muchas inputs y siempre tendrán que filtrarse para el tipo deseado). La tabla de usuario está bien con el ID autoincrementado y como key principal. Para las publicaciones, también agregaría una identificación autoincrementada como key principal y user_id como key externa (también puede decidir qué hacer al eliminar, por ejemplo, con cascada, todas sus publicaciones también se eliminarán automáticamente).

Para los comentarios y "Me gusta" puedes crear tablas separadas con las dos foreign keys user_id y post_id (ejemplo simple, como esto, solo te pueden gustar las publicaciones y nada más, pero si no hay muchos types de Me gusta, podría ser bueno crear un post_likes y algunas otras …_ tablas de Me gusta, debes pensar en cómo se consultan generalmente estos datos, si esos "me gusta" son en su mayoría independientes entre sí, probablemente sea una buena opción).