Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

diferença entre HAVING e WHERE

Fiquei com uma dúvida, porque nesse caso:

select c.nome, avg(n.nota) from nota n
join resposta r on r.id = n.resposta_id
join exercicio e on e.id = r.exercicio_id
join secao s on s.id = e.secao_id
join curso c on c.id = s.curso_id
join aluno a on a.id = r.aluno_id
where a.nome like '%Santos%' or a.nome like '%Silva%'
group by c.nome;

eu pude usar o WHERE junto com GROUP BY e

nesse caso:

select a.nome, c.nome, avg(n.nota) from 
nota n
join resposta r on r.id = n.resposta_id
join exercicio e on e.id = r.exercicio_id
join secao s on s.id = e.secao_id
join curso c on c.id = s.curso_id
join aluno a on a.id = r.aluno_id
group by c.nome, a.nome
having avg(n.nota) < 5

não posso usar o WHERE, tenho que utilizar o HAVING no lugar???

tentei usar o HAVING no primeiro caso e também dá erro, por favor me expliquem o motivo.

obrigado.

2 respostas
solução!

O HAVING é utilizado para avaliar um conjunto de resultados, no caso da segunda query, se fez um agrupamento entre a.nome, c.nome, e um campo calculado avg(n.nota). Como se usou uma função agregada, é necessário usar GROUP para agrupar os resultados. Somente depois de obtidos os resultados é que se pode filtrar usando HAVING, neste caso para listar apenas aqueles que tiveram a média menor que 5.

Já O WHERE é para filtrar o conjunto de linhas que vai ser retornado como resultado.

A estrutura das duas consultas é igual, o que muda são os campos utilizados e a forma de filtrar e avaliar o resultado. No caso do primeiro exemplo, se utiliza apenas c.nome e um campo calculado avg(n.nota), por causa disso, é necessário agrupar os resultados. O WHERE entra para filtrar as linhas que vão ser utilizadas para montar o resultado, no caso somente alunos que tenham Santos ou Silva no nome.

Perceba que neste caso você não pode filtrar por média menor que 5 no WHERE. É necessário primeiro gerar o conjunto de resultados, para depois fazer o filtro.

Então o WHERE entra ANTES de gerar o resultado, e o HAVING entra DEPOIS de obter o resultado.

obrigado pela explicação, bem mais claro agora...