Este mensaje de error
generalmente se debe a la definición de sus columnas y tablas. Por lo general, significa que a cada lado de un signo igual hay diferentes intercalaciones. Lo que debes hacer es elegir uno e incluir esa decisión en tu consulta.
El problema de intercalación aquí estaba en CROSS JOIN de @prev_value que necesitaba una intercalación explícita para ser utilizada.
También cambié ligeramente la lógica "row_number" a una sola unión cruzada y moví la lógica if a los extremos de la lista de selección.
Algunos datos de muestra se muestran a continuación. Se necesitan datos de muestra para probar las consultas. Cualquiera que intente responder a su pregunta con ejemplos de trabajo necesitará datos. La razón por la que lo incluyo aquí es doble.
- para que entienda cualquier resultado que presente
- para que en el futuro, cuando haga otra pregunta relacionada con SQL, comprenda la importancia de proporcionar datos. No solo es más conveniente para nosotros que usted haga esto. Si el autor de la pregunta proporciona los datos de muestra, entonces el autor de la pregunta ya lo entenderá; no será una invención de un extraño que ha dedicado parte de su tiempo a ayudar.
Datos de muestra
Tenga en cuenta que faltan algunas columnas en las tablas, solo se han incluido las columnas especificadas en los detalles de la tabla.
Estos datos de muestra tienen 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 orden de las columnas de la lista de selección para que pueda ver fácilmente algunos datos relacionados con los comentarios cuando presente los resultados. Estudie los resultados que se proporcionan para que pueda comprender lo que hará la consulta. Las columnas precedidas por # no existen en los datos de muestra con los que estoy trabajando por las razones que ya he indicado.
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 funcional de esta consulta en SQLFiddle
| 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án 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 añadidas]
En un comentario a continuación, se reveló que no quería 2 filas por publicación y que esto sería una solución fácil. Bueno, es fácil PERO hay opciones y las opciones las dicta el usuario en forma de requisitos. SI la pregunta tuviera un "resultado esperado", entonces sabríamos qué opción elegir. No obstante, 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
| 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 lista 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
| 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 manera diferente. La primera consulta (comportamiento predeterminado) 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 cuenta 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 comprender los resultados presentados aquí, pero también 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, a estas alturas, también sepa que es normal que SQL presente datos en varias filas. Si no desea ese comportamiento normal, sea específico sobre lo que realmente desea en su pregunta.
Posdata. Para incluir otra subconsulta para "sigue", puede usar una subconsulta similar a la que ya tiene. Puede agregarse 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 obtener más información, la consulta general puede volverse más lenta en proporción al crecimiento de sus datos. Una vez que se haya decidido por la funcionalidad que realmente necesita, puede valer la pena considerar qué índices necesita en esas tablas. (Creo que se le recomendaría que pida ese consejo por separado y, si lo hace, asegúrese de incluir 1. el DDL completo de sus tablas y 2. un plan explicativo de la consulta).