3
respostas

6. Dúvida no exemplo de de Sub-queries

Quando tentei executar o código do exemplo do capítulo 6,

SELECT 
    a.nome,
    AVG(n1.nota) AS media,
    AVG(n1.nota) - (SELECT 
                        AVG(n2.nota)
                    FROM
                        nota n2
                            JOIN
                        resposta r2 ON n2.resposta_id = r2.id
                    WHERE
                        r2.aluno_id <> a.id) AS diferenca
FROM
    nota n1
        JOIN
    resposta r ON r.id = n1.resposta_id
        JOIN
    exercicio e ON e.id = r.exercicio_id
        JOIN
    secao s ON s.id = e.secao_id
        JOIN
    aluno a ON a.id = r.aluno_id
GROUP BY a.nome;

obtive o seguinte erro:

Error Code: 1055. Expression #3 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'sql2.a.id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by

Ok.

Verificando no "pai dos burros" (Stack overflow : http://stackoverflow.com/questions/25800411/mysql-isnt-in-group-by) e relendo com calma a mensagem de erro, percebi que "a.id" não estava incluído no GROUP BY.

Peço a gentileza de corrigirem o exemplo do capítulo...

3 respostas

Oi Rafael, perdão, não achei o local exato onde está referenciado o id na query, olhei pelos exemplos do capítulo 6, que você sugeriu.

Olá, Alberto! no exemplo do capítulo (bem no final da seção que vem logo após o vídeo) , aparece uma consulta SQL com uma sub-query para retornar o valor da média geral:

(SELECT 
     AVG(n2.nota)
  FROM
      nota n2
         JOIN
      resposta r2 ON n2.resposta_id = r2.id
  WHERE
      r2.aluno_id <> a.id) AS diferenca

Observe que, dentro da sub-query está referenciado o id do aluno "a.id".

Esta é a terceira coluna/expressão do SELECT (a primeira é "a.nome" e a segunda "AVG(n1.nota)".)

Pelo que pude entender do que li no stack overflow (veja a referência), se apareceu como uma coluna lá no SELECT, tem que aparecer no GROUP BY. A exceção é se for uma função agregadora (como é o caso de AVG()")

A query completa tem que ficar assim:

SELECT 
    a.nome AS Aluno,
    AVG(n1.nota) AS Media,
    AVG(n1.nota) - (SELECT 
                        AVG(n2.nota)
                    FROM
                        nota n2
                            JOIN
                        resposta r2 ON n2.resposta_id = r2.id
                    WHERE
                        r2.aluno_id <> a.id) AS Diferenca
FROM
    nota n1
        JOIN
    resposta r ON r.id = n1.resposta_id
        JOIN
    exercicio e ON e.id = r.exercicio_id
        JOIN
    secao s ON s.id = e.secao_id
        JOIN
    aluno a ON a.id = r.aluno_id
GROUP BY a.nome, a.id;

Observe nesta última linha o "a.id".

Acho que também há um equívoco ao identificar o n (apelido da tabela nota) como elemento externo à sub-query. Entendo que seja a (apelido da tabela aluno), mas eu posso estar errado.

Não tinha visto o id, tem razão. O lance do que ta no select, e não é função de agregação, ter que também estar no group by faz todo sentido. Quando vc agrupa, basicamente vc está juntando as linhas, então se vc agrupou tudo pelo nome, vc perdeu esses ids. E acho que também tem razão em relação ao alias usado na subquery. Como foi que vc identificou, você pode sugerir a mudança clicando botão "sugerir melhoria" no canto direito inferior da atividade?