Ir para conteúdo

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Romulo22

[Resolvido] Select com GROUP BY mesmo sem registro correspondente

Recommended Posts

Olá,

Estou com o seguinte problema para uma consulta com GROUP BY

Tenho as seguintes tabelas para serem utilizadas na consulta: "Categorias, Produtos, Fabricante, LojaProd, NotaProd"

 

O intuito da consulta é exibir o nome da categoria do produto, id, nome do produto, nome do fabricante, valor do produto e a média da nota (nota data pelos usuários ao produto)

 

Estou usando a seguinte consulta e funcionando muito bem até determinada parte:

 

SELECT c.nomeCateg, p.id, p.nomeProd, f.nomeFabr, l.valor, CEIL(AVG(n.nota))

FROM Categorias c, Produtos p, Fabricante f, LojaProd l, NotaProd n

WHERE p.lancamento='0' AND p.idCateg = c.id AND p.idFabr = f.id AND p.id = l.idProd AND p.id = n.idProd

GROUP BY n.idProd

ORDER BY p.id

 

O problema é quando nenhum usuário avaliou o produto ainda. Pois a consulta só vai exibir o registro que tenha nota cadastra. E queria exibir os produtos da tabela produtos que tivessem o registro lancamento = 0 mesmo que não tivessem um registro com uma nota correspondente na tabela de notas (mesmo que o produto não tenha sido avaliado).

 

A tabela notaProd possui o "id, idProd,IdUser e Nota". Atualmente pra poder funcionar a consulta eu tenho sempre que cadastrar um produto cadastrar um registro na fake na tabela de notas com o id do produto um id de usuário = 0(pra não ficar cadastrado no nome de ninguém) e deixar a nota como null. Aí sim os produtos com e sem nota cadastrada são exibidos na consulta.

 

Agradeço desde já quem puder ajudar com o problema

Compartilhar este post


Link para o post
Compartilhar em outros sites

SQL só retorna dados que existam, para casos como estes é preciso fazer um artifício, uma maneira ...

 

select nomeCateg,id,nomeProd,sum(valor) valor , sum(media) media
from
(
SELECT c.nomeCateg, p.id, p.nomeProd, f.nomeFabr, l.valor, CEIL(AVG(n.nota)) media
FROM Categorias c, Produtos p, Fabricante f, LojaProd l, NotaProd n
WHERE p.lancamento='0' AND p.idCateg = c.id AND p.idFabr = f.id AND p.id = l.idProd AND p.id = n.idProd
GROUP BY n.idProd

union all 

SELECT c.nomeCateg, p.id, p.nomeProd, f.nomeFabr, 0 valor, 0 media
FROM Categorias c, Produtos p, Fabricante f
WHERE p.lancamento='0' AND p.idCateg = c.id AND p.idFabr = f.id 
) virtual
group by nomeCateg,id,nomeProd
ORDER BY virtual.id

Compartilhar este post


Link para o post
Compartilhar em outros sites

Hum... Entendi. Perfeito!

Muito obrigado.

Só ajustei a consulta pra me continuar me mostrando os valores de média sem somar os preços. Mostrando os valores originais do produto e setando o valor pra null ao invés de 0 caso não tenha nota.

Ficou assim:

 

select nomeCateg,id,nomeProd, valor, media

from

(

SELECT c.nomeCateg, p.id, p.nomeProd, f.nomeFabr, l.valor, CEIL(AVG(n.nota)) media

FROM Categorias c, Produtos p, Fabricante f, LojaProd l, NotaProd n

WHERE p.lancamento='0' AND p.idCateg = c.id AND p.idFabr = f.id AND p.id = l.idProd AND p.id = n.idProd

GROUP BY n.idProd

 

union all

 

SELECT c.nomeCateg, p.id, p.nomeProd, f.nomeFabr, l.valor, null media

FROM Categorias c, Produtos p, Fabricante f, lojaProd l

WHERE p.lancamento='0' AND p.idCateg = c.id AND p.idFabr = f.id

) virtual

group by nomeCateg,id,nomeProd

ORDER BY virtual.id

 

Opa. Acabei de ver que esta repedindo o valor do primeiro registro nos registros que não tem nota.

Vou ter que dar uma olhada novamente pra ver o que aconteceu.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Por isto o SUM, pode também no sql de "baixo" fazer um NOT EXISTS com a tabela NotaProd , evita a duplicidade.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Foi apenas falta de atenção.

Faltou um AND no terceiro SELECT pra ficar assim AND p.id = l.idProd

 

Agora está tudo funcionando.

 

select nomeCateg,id,nomeProd, valor, media

from

(

SELECT c.nomeCateg, p.id, p.nomeProd, f.nomeFabr, l.valor, CEIL(AVG(n.nota)) media

FROM Categorias c, Produtos p, Fabricante f, LojaProd l, NotaProd n

WHERE p.lancamento='0' AND p.idCateg = c.id AND p.idFabr = f.id AND p.id = l.idProd AND p.id = n.idProd

GROUP BY n.idProd

 

union all

 

SELECT c.nomeCateg, p.id, p.nomeProd, f.nomeFabr, l.valor, null media

FROM Categorias c, Produtos p, Fabricante f, LojaProd l

WHERE p.lancamento='0' AND p.idCateg = c.id AND p.idFabr = f.id AND p.id = l.idProd

) virtual

group by nomeCateg,id,nomeProd

ORDER BY virtual.id

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.