Jump to content

Archived

This topic is now archived and is closed to further replies.

matheusmarson

Uso de rank no mysql

Recommended Posts

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


Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

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!

Share this post


Link to post
Share on other sites

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...

Share this post


Link to post
Share on other sites

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) desc

Share this post


Link to post
Share on other sites

Veja a imagem do resultado

Note que o rank não está sendo montado corretamente como deveria

 

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

Share this post


Link to post
Share on other sites

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...

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

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...

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

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 )

Share this post


Link to post
Share on other sites

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

resultado1.jpg

Share this post


Link to post
Share on other sites

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!

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

×

Important Information

Ao usar o fórum, você concorda com nossos Terms of Use.