Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
Olá a todos.
Alguém saberia me dizer porque minha query abaixo em um determinado momento ela zera o valor do @rank_fabricante mesmo o valor da variável @fabricante_atual ainda ser igual ao f.id
Ou seja pela lógica ela deveria zerar o valor do @rank_fabricante apenas quando o valor de f.id fosse diferente de @fabricante_atual não?
SELECT f.id, f.nome_fantasia, c.categoria, c.id as id_categoria, COUNT(c.categoria) qtd, @rank_fabricante:= IF(@fabricante_atual = f.id, @rank_fabricante + 1, 0) AS rank_fabricante, @fabricante_atual := f.id
FROM produtos p, produtos_categorias c, fabricantes f
WHERE p.id_categoria = c.id AND p.id_fabricante=f.id
GROUP BY f.id, f.nome_fantasia, c.categoria, c.id
ORDER BY f.nome_fantasia, COUNT(c.categoria) desc
Mora, agora ele não zera o @rank_fabricante se o fabricante for outro
Foi um "chute", desculpe.
Alterei um pouco a consulta e ainda continua o mesmo problema veja,
SET @rank_fabricante:= @fabricante_atual:= 0;
SELECT f.id, f.nome_fantasia, c.categoria, c.id as id_categoria, COUNT(c.categoria) qtd, @rank_fabricante:= IF(@fabricante_atual <> f.id, 0, @rank_fabricante + 1) AS rank_fabricante, @fabricante_atual:= f.id
FROM produtos p, produtos_categorias c, fabricantes f
WHERE p.id_categoria = c.id AND p.id_fabricante=f.id
GROUP BY f.id, c.id
ORDER BY f.id, COUNT(c.categoria) DESC
O mysql está zerando o valor do @rank_fabricante onde não deveria. Estranho demais!
Resolve se remover f.nome_fantasia do GROUP BY e do ORDER BY e c.categoria do GROUP BY?
SELECT f.id, f.nome_fantasia, c.categoria, c.id as id_categoria, COUNT(c.categoria) qtd, @rank_fabricante:= IF(@fabricante_atual = f.id, @rank_fabricante + 1, 0) AS rank_fabricante, @fabricante_atual := f.id
FROM produtos p, produtos_categorias c, fabricantes f
WHERE p.id_categoria = c.id AND p.id_fabricante=f.id
GROUP BY f.id, c.id
ORDER BY f.id, COUNT(c.categoria) desc
Para exibir somente os 4 primeiros itens você coloca um HAVING rank_fabricante < 4 antes do ORDER BY.
Vou aguardar a resposta...
oi lokaodomau com o having até que ele limita para 4 registros por fabricante porem ele monta o rank errado pois não exibe as categorias com mas produtos do fabricante
Ficou assim:
SET @fabricante_atual:=@rank_fabricante:=1;
SELECT f.id, f.nome_fantasia, c.categoria, c.id as id_categoria, COUNT(c.categoria) qtd,
@rank_fabricante:= IF(@fabricante_atual <> f.id, @rank_fabricante + 1, 1) AS rank,
@fabricante_atual := f.id
FROM produtos p, produtos_categorias c, fabricantes f
WHERE p.id_categoria = c.id AND p.id_fabricante=f.id
GROUP BY p.id_fabricante, p.id_categoria HAVING rank < 4
ORDER BY f.id, COUNT(c.categoria) descEntão o que está exibindo?
Veja a imagem do resultado
Note que o rank não está sendo montado corretamente como deveria
/applications/core/interface/imageproxy/imageproxy.php?img=http://www.jmsolucoes.com.br/resultado.jpg&key=1a56a96d4cd60efbb8b20785e6c95fe153add14244b64415febe31a68e62b2a7" alt="resultado.jpg" />
Outra coisa
As categorias mostradas não são as que tem mais quantidade. Mas isso eu creio que é pela montagem errada do rank
Pelo que eu havia entendido, era isso que você queria...
Os 4 produtos mais vendidos por categoria do fabricante, está ordenando os fabricantes e depois as categorias, até esse ponto está correta a consulta.
Não use o campo id_categoria para se basear em nada, eu ainda não entendi bem como funciona a exibição das linhas que estão agrupadas, é bem relativo...
Lokaodomau
Oque preciso é mostrar os fabricantes e as categorias dele qu mais tem produtos cadastrados.
Não os mais vendidos
na imagem ele está mostrando a categorias do fabricante porém estas não são as que tem mais produtos cadastrados.
O rank ele monta errado. Esse é o ponto eu imagino
por ex: os fabricantes com uma categoria apenas o rank deveria ser 1
com 2 categorias apenas deveria ser 1 e 2
E isso não ocorre
Obrigado pela força
Esta tabela é a tabela de cadastro de produtos ou de vendas?
Se tiver uma tabela de produtos cadastrados, faz essa consulta em cima dos cadastrados, caso não tenha a tabela de produtos cadastrados, somente a de venda, tenta fazer um "COUNT( DISTINCT id_produto ) produtos_distintos", veja se resolve...
Essa tabela é a de produtos
Tenho essa estrutura:
Fabricantes (id, razao_social)
Categorias (id, categoria)
Produtos (id, titulo, preco, id_categoria, id_fabricante)
Lembrando: Preciso das 4 categorias com mais produtos de cada fabricante
Foi isso mesmo que foi feito, primeiro agrupamos o fabricante, para que não repita, depois agrupamos as categorias, para que não repitam também, ao utilizar o COUNT, estamos contando quantos registros de cada categoria para cada fabricante, mesmo que estejamos contando a partir do campo categoria, este número somente não será real se houver linhas em que este campo estiver com valor NULL, como todo produto deve possuir uma categoria, acredito que este não seja um problema...
Se COUNT(c.categoria) não está funcionando, tente substitui-lo por COUNT( DISTINCT c.categoria )
O COUNT(c.categoria) está funcionando sim
o Erro está aqui IF(@fabricante_atual <> f.id, @rank_fabricante + 1, 1) AS rank,
o rank é que é formado errado
A lógica disso seria o rank ir somando 1 para cada registro de categoria do fabricante. E a categoria seria ordenada pela quantidade, mas não está acontecendo isso
Veja no resultado da pesquisa como ele retorna o rank e em vermelho ao lado como deveria retonar
/applications/core/interface/imageproxy/imageproxy.php?img=http://www.jmsolucoes.com.br/resultado1.jpg&key=de1fbfc9b3598c23db7ecbab663f49994af797ca03b517409a700444539eb7ee" alt="resultado1.jpg" />
Tenta assim:
SELECT f.id, f.nome_fantasia, c.categoria, c.id as id_categoria, COUNT(c.categoria) qtd, @rank_fabricante:= IF(@fabricante_atual = f.id, @rank_fabricante + 1, 0) AS rank_fabricante, @fabricante_atual := f.id
FROM produtos p, produtos_categorias c, fabricantes f
WHERE p.id_categoria = c.id AND p.id_fabricante=f.id
GROUP BY f.id, c.id
ORDER BY f.id, COUNT(c.categoria) desc
Desculpe, acho que a consulta ficou a mesma... Segue a consulta correta!
SELECT
f.id,
f.nome_fantasia,
c.categoria,
c.id AS id_categoria,
COUNT(c.categoria) ASqtd,
@count:= IF( @fab_id = p.id_fabricante, @count + 1, 1 ) AS rank,
@fab_id:= p.id_fabricante AS fab_id
FROM produtos p, produtos_categorias c, fabricantes f
WHERE p.id_categoria = c.id AND p.id_fabricante = f.id
GROUP BY f.id, c.id
HAVING rank <= 4
ORDER BY f.id, COUNT(c.categoria)DESC
Assim vai pegar somente as 4 categorias com mais produtos cadastrados, veja se agora funciona!Também não deu certo não e agora nem limitar as categorias limita.
E o rank ainda continua sendo formado errado
Veja:
/applications/core/interface/imageproxy/imageproxy.php?img=http://www.jmsolucoes.com.br/resultado2.jpg&key=24f7a50f9e49699c629919057e7c35f1c23a5ac7cd67c2888444fc293bd2401c" alt="resultado2.jpg" />
Olha, ficou um pouco extensa, mas acho que resolvi:
SELECT
x.id,
f.nome_fantasia,
c.categoria,
x.id_categoria AS id_categoria,
x.qtd,
@count:= IF( @fab_id = x.id_fabricante, @count + 1, 1 ) AS rank,
@fab_id:= x.id_fabricante AS fab_id
FROM
(
SELECT p.id, p.titulo, p.id_categoria, p.id_fabricante, COUNT(p.id_categoria) as qtd FROM produtos p GROUP BY p.id_fabricante, p.id_categoria
) as x,
produtos_categorias c,
fabricantes f
WHERE x.id_categoria = c.id AND x.id_fabricante = f.id
GROUP BY x.id_fabricante, x.id_categoria
HAVING rank <= 4
Se você remover o GROUP BY, HAVING e ORDER BY vai entender, a variável do MySQL recebe os valores depois de executar o WHERE e antes dessas outras clausulas, na minha tabela funcionava, porque eu inseri em ordem de fabricante e categoria, mas como a sua é uma tabela real, que está em execução, os registros não são necessariamente inseridos na mesma ordem que eu fiz, então eu criei uma subquery e usei a variável depois da contagem, dessa forma o rank é criado corretamente.Grande lokodomau é isso mesmo
Só um porém as 4 categorias mostradas não são as que tem mais produtos cadastrados
Veja na imagem o nome_fantasia Outros para vc ver
/applications/core/interface/imageproxy/imageproxy.php?img=http://www.jmsolucoes.com.br/resultado3.jpg&key=0770864aefee2e5cd1ee71cdd03b03ead033f84d3ed4049e7826ff94d1435f4e" alt="resultado3.jpg" />
Acredito que seja porque não tenha sido usado o HAVING rank <= 4
Não, não é não seu eu limitar com Having ele mostra a apenas as 4 mas não são as 4 com mais produtos
O rank não ordenou correto isso
Veja na imagem que vc vai ver que o rank não está correto em relação a qtd
Finalmente, acho que entendi agora...
SELECT
x.id,
f.nome_fantasia,
c.categoria,
x.id_categoria AS id_categoria,
x.qtd,
@count:= IF( @fab_id = x.id_fabricante, @count + 1, 1 ) AS rank,
@fab_id:= x.id_fabricante AS fab_id
FROM
(
SELECT p.id, p.titulo, p.id_categoria, p.id_fabricante, COUNT(p.id_categoria) as qtd FROM produtos p GROUP BY p.id_fabricante, p.id_categoria ORDER BY p.id_fabricante, qtd DESC
) as x,
produtos_categorias c,
fabricantes f
WHERE x.id_categoria = c.id AND x.id_fabricante = f.id
GROUP BY x.id_fabricante, x.id_categoria
HAVING rank <= 4
Como não tinha ORDER BY na subquery, o próprio banco ordena o resultado conforme o GROUP BY, então estava ordenando pelos id do fabricante e id da categoria...GRANDE lokaodomau!!! Perfeito! Era isso mesmo que eu precisava
Resolvido
Foi difícil e demorado, mas conseguimos, hehehe.
Cara perfeito! Muito obrigado. Irá ajudar muita gente isso. Valew!
Problema! Quando foi colocar a query no php não funcionou.
O rank não incrementa
O código:
$query ="SELECT x.id, f.nome_fantasia, c.categoria, x.id_categoria AS id_categoria, x.qtd,
@count:= IF(@fab_id = x.id_fabricante, @count:=@count + 1, 1 ) AS rank,
@fab_id:= x.id_fabricante AS fab_id
FROM(
SELECT p.id, p.titulo, p.id_categoria, p.id_fabricante, COUNT(p.id_categoria) as qtd FROM produtos p GROUP BY p.id_fabricante, p.id_categoria ORDER BY p.id_fabricante, qtd DESC
) as x, produtos_categorias c, fabricantes f
WHERE x.id_categoria = c.id AND x.id_fabricante = f.id
GROUP BY x.id_fabricante, x.id_categoria
HAVING rank <= '4'";
$sql = mysql_query($query) or die ("erro: " . mysql_errno($conn) . ", " . mysql_error($conn));
while($row = @mysql_fetch_array($sql)){Coloca o erro que mostrou no PHP
Nao seria ?
SELECT f.id, f.nome_fantasia, c.categoria, c.id as id_categoria, COUNT(c.categoria) qtd, @rank_fabricante:= IF(@fabricante_atual = f.id, @rank_fabricante + 1, @rank_fabricante) AS rank_fabricante, @fabricante_atual := f.id
FROM produtos p, produtos_categorias c, fabricantes f
WHERE p.id_categoria = c.id
AND p.id_fabricante=f.id
GROUP BY f.id, f.nome_fantasia, c.categoria, c.id
ORDER BY f.nome_fantasia, COUNT(c.categoria) desc