Esta mensagem de erro
é normalmente devido à definição de suas colunas e tabelas. Geralmente significa que em ambos os lados de um sinal de igual existem diferentes agrupamentos. O que você precisa fazer é escolher um e incluir essa decisão em sua consulta.
O problema de agrupamento aqui estava no CROSS JOIN de @prev_value que precisava de um agrupamento explícito para ser usado.
Também alterei ligeiramente a lógica "row_number" para uma única junção cruzada e movi a lógica if para os extremos da lista de seleção.
Alguns dados de exemplo são exibidos abaixo. Os dados de amostra são necessários para testar as consultas. Qualquer pessoa que tente responder à sua pergunta com exemplos práticos precisará de dados. A razão pela qual estou incluindo aqui é dupla.
- para que você entenda qualquer resultado que eu apresentar
- para que, no futuro, quando você fizer outra pergunta relacionada ao SQL, entenda a importância de fornecer dados. Não é apenas mais conveniente para nós que você faça isso. Se o solicitante fornecer os dados de amostra, ele já o entenderá - não será uma invenção de algum estranho que dedicou parte de seu tempo para ajudar.
Dados de amostra
Observe que algumas colunas estão faltando nas tabelas, apenas as colunas especificadas nos detalhes da tabela foram incluídas.
Esses dados de amostra têm 5 comentários em uma única postagem (nenhuma curtida é registrada)
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') ;
[Comportamento padrão SQL:2 linhas por consulta de postagem]
Esta foi a minha consulta inicial, com algumas correções. Mudei a ordem das colunas da lista de seleção para que você veja facilmente alguns dados relacionados a comentários quando eu apresentar os resultados. Por favor, estude os resultados que são fornecidos para que você possa entender o que a consulta fará. Colunas precedidas por # não existem nos dados de amostra com os quais estou trabalhando por motivos que já observei.
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
;
Veja uma demonstração funcional desta consulta no 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 |
Existem 2 LINHAS - como esperado. Uma linha para o comentário mais recente e outras linhas para o próximo comentário mais recente. Este é um comportamento normal para SQL e até que um comentário fosse adicionado nesta resposta, os leitores da pergunta assumiriam que esse comportamento normal seria aceitável.
A questão carece de um "resultado esperado" claramente articulado.
[Opção 1:uma linha por consulta de postagem, com até 2 comentários, colunas adicionadas]
Em um comentário abaixo, foi revelado que você não queria 2 linhas por postagem e isso seria uma solução fácil. Bem, é meio fácil, MAS existem opções e as opções são ditadas pelo usuário na forma de requisitos. SE a pergunta tivesse um "resultado esperado", saberíamos qual opção escolher. No entanto, aqui está uma opção
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
;
Veja a segunda consulta trabalhando no SQLFiddle
Resultados da 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 |
** Opção 2, concatenar os comentários mais recentes em uma única lista separada por vírgulas **
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
Veja esta terceira consulta trabalhando no SQLFiddle
Resultados da 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 |
** Resumo **
Eu apresentei 3 consultas, cada uma mostra apenas os 2 comentários mais recentes, mas cada consulta faz isso de uma forma diferente. A primeira consulta (comportamento padrão) exibirá 2 linhas para cada postagem. A opção 2 adiciona uma coluna, mas remove a segunda linha. A opção 3 concatena os 2 comentários mais recentes.
Observe que:
- A questão não tem definições de tabela cobrindo todas as colunas
- A questão não tem dados de amostra, o que dificulta a compreensão dos resultados apresentados aqui, mas também dificulta a preparação de soluções
- A pergunta também carece de um "resultado esperado" definitivo (a saída desejada) e isso levou a uma maior complexidade na resposta
Espero que as informações adicionais fornecidas sejam de alguma utilidade e que agora você também saiba que é normal que o SQL apresente dados como várias linhas. Se você não deseja esse comportamento normal, seja específico sobre o que você realmente deseja em sua pergunta.
Pós-escrito. Para incluir outra subconsulta para "follows", você pode usar uma subconsulta semelhante à que você já possui. Pode ser adicionado antes ou depois dessa subconsulta. Você também pode vê-lo em uso em sqlfiddle aqui
LEFT JOIN (
SELECT
COUNT(*) FollowCNT
, IdOtherUser
FROM Activity
WHERE type = 'Follow'
GROUP BY
IdOtherUser
) F ON USERS.id = F.IdOtherUser
Embora a adição de outra subconsulta possa resolver seu desejo de obter mais informações, a consulta geral pode ficar mais lenta em proporção ao crescimento de seus dados. Depois de definir a funcionalidade que você realmente precisa, pode valer a pena considerar quais índices você precisa nessas tabelas. (Acredito que você seria aconselhado a pedir esse conselho separadamente e, se o fizer, certifique-se de incluir 1. o DDL completo de suas tabelas e 2. um plano de explicação da consulta.)