Ir para conteúdo

POWERED BY:

Arquivado

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

Beraldo

[Resolvido] Contar quantidade de categorias-filhas de uma categor

Recommended Posts

Olá, pessoal

 

Tenho um sistema de categorias e sub-categorias, onde uso apenas a tabela abaixo:

 

CREATE TABLE categorias(
id INT(5) UNSIGNED NOT NULL AUTO_INCREMENT,
id_pai INT(5) UNSIGNED NOT NULL,
nome VARCHAR(20) NOT NULL,
PRIMARY KEY (id)
) DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;

 

 

imaginemos o seguinte conjunto de dados

INSERT INTO categorias(id, id_pai, nome) VALUES
(1, 0, 'A Empresa'),
(2, 1, 'Sobre Nós'),
(3, 1, 'Objetivos'),
(4, 3, 'Objetivo dos nossos clientes'),
(5, 0, 'Contato'),
(6, 0, 'Produtos');

id_pai = 0 significa que a categoria é raiz (não é sub-categoria)

 

Com esta query, retorno a lista de categorias:

 

mysql> SELECT id, id_pai, nome FROM categorias
+----+--------+----------------------+
| id | id_pai | nome                 |
+----+--------+----------------------+
|  1 |      0 | A Empresa            | 
|  2 |      1 | Sobre Nós           | 
|  3 |      1 | Objetivos            | 
|  4 |      3 | Objetivo dos nossos  | 
|  5 |      0 | Contato              | 
|  6 |      0 | Produtos             | 
+----+--------+----------------------+
6 rows in set (0,00 sec)

 

Preciso contar o número de categorias-filhas de cada categoría. Sei que posso usar mais de uma query, mas acho que deve haver alguma forma de fazer isso em uma única consulta.

 

Eu gostaria de um resultado assim:

 

mysql> ????????
+----+--------+----------------------+
| id | id_pai | nome                 | filhas
+----+--------+----------------------+
|  1 |      0 | A Empresa            | 2
|  2 |      1 | Sobre Nós           |  0
|  3 |      1 | Objetivos            | 1
|  4 |      3 | Objetivo dos nossos  | 0
|  5 |      0 | Contato              | 0
|  6 |      0 | Produtos             | 0
+----+--------+----------------------+
6 rows in set (0,00 sec)

 

Alguma sugestão? :)

 

 

Abraços

Compartilhar este post


Link para o post
Compartilhar em outros sites

meio estranho fazer a tabela com auto relacionamento.

 

pra trazer a quantidade de filhos seria:

select nome, 
(select count(*) from categorias c2 where c1.id = c2.id_pai) total
from categorias c1 where id_pai = 0

 

 

a subquery, ferra com a performance, vai ter muitos dados?

O my sql tem over partition??

Compartilhar este post


Link para o post
Compartilhar em outros sites

cria uma função

create or replace function f_retorna_pai (p_filho number) return number is
 v_id       number;
 v_id_pai   number;
 v_id_filho number;
begin
 v_id_filho := p_filho;
 loop
   select id, id_pai
     into v_id, v_id_pai
     from TESTE_EU t
    where id = v_id_filho;

    if v_id_pai = 0 then
      exit; -- é o pai
    else
      v_id_filho := v_id_pai;
    end if;
 end loop;
 return v_id;
end;

 

e depois manda o select

select id, id_pai, nome, 
(select count(*) from TESTE_EU c2 where f_retorna_pai(c2.id) = c1.id and c2.id_pai <> 0) total
from TESTE_EU c1 where id_pai = 0

 

cadê a minha cerveja????

Compartilhar este post


Link para o post
Compartilhar em outros sites

De todo jeito tem subselect.

Eu que quero a cerveja.

 

Se falar em performance, por function eh melhor, mas vai depender da estrutura e indices.

Compartilhar este post


Link para o post
Compartilhar em outros sites

meio estranho fazer a tabela com auto relacionamento.

DBA reclama, mas, como é 1 pra 1, funciona certinho :P

 

 

pra trazer a quantidade de filhos seria:

select nome, 
(select count(*) from categorias c2 where c1.id = c2.id_pai) total
from categorias c1 where id_pai = 0

na mosca! :clap:

 

 

a subquery, ferra com a performance, vai ter muitos dados?

Na verdade, é para um visitante do meu blog. Ele que fez a pergunta e aí me surgiu a dúvida. Mas creio que não sejam muitos dados, já que é apenas para um menu.

 

 

O my sql tem over partition??

Nem sei o que é isso. Muito menos sei se o mysql tem :P

 

 

De todo jeito tem subselect.

é, acho que não tem escapatória mesmo.

 

 

Eu que quero a cerveja.

Cara, essa dúvida envolveu quase 10 pessoas... teve até gente do Rio :lol:

Vamos pro bar e tomamos todas todos juntos! :joia:

 

 

Em suma, a seguinte consulta resolve o problema:

select id, nome,  (select count(*) from categorias c2 where c1.id = c2.id_pai) total from categorias c1;

 

 

Agradeço a ajuda de todos!

 

 

Abraços

Compartilhar este post


Link para o post
Compartilhar em outros sites

Nem sei o que é isso. Muito menos sei se o mysql tem :P

Não tem,

Partition se me lembro bem é pra dar um rewind no contador (ROW_NUMBER) quando um novo grupo iniciar.

Over é pra determinar um partition ou ordenação antes da aplicação da cláusula em si.

 

Ah, sei lá, quando li sobre SQL Server o que eu entendi foi isso, mas no MySQL não tem nisso, tem que fazer não mão (até onde eu me lembre).

 

:pinch:

Compartilhar este post


Link para o post
Compartilhar em outros sites

Boa tarde!
Desculpe reviver o topico , mas surgiu o mesmo problema pra mim!

Eu tenho um select do sqlserver pronto pra paginaçao, porém preciso converter pra mysql
Alguem saberia indicar como fazer ?

o select é esse:

SELECT * FROM (   
	SELECT ROW_NUMBER() OVER(ORDER BY B.OrdemC, B.OrdemS, B.OrdemP) AS Pagina, B.* FROM (
		SELECT   
		P.CodProduto,   
		P.CodCategoria,   
		C.Titulo as TituloCategoria,   
		ifNull(P.CodSubCategoria, 0),   
		ifNull(S.Titulo, '') as TituloSubCategoria,   
		P.Titulo as Titulo,   
		P.Subtitulo,   
		P.descricao,   
		P.ordem as OrdemP,   
		P.ativo,   
		C.Ordem as OrdemC,   
		S.Ordem as OrdemS 
		FROM 
			GC_Produtos P 
			INNER JOIN GC_ProdutosCategorias C ON 
				P.CodCategoria = C.CodCategoria 
			LEFT JOIN GC_ProdutosSubCategorias S ON 
			P.CodSubCategoria = S.CodSubCategoria 
		WHERE P.ativo = 1;   
	) B 
) R 
WHERE R.Pagina 
BETWEEN @PaginaInicial AND @PaginaFinal 
ORDER BY R.Pagina; 

SELECT COUNT(1) AS Total FROM ( 
	SELECT   
	P.CodProduto,   
	P.CodCategoria,   
	C.Titulo as TituloCategoria,   
	ifNull(P.CodSubCategoria, 0),   
	ifNull(S.Titulo, '') as TituloSubCategoria,   
	P.Titulo as Titulo,   
	P.Subtitulo,   
	P.descricao,   
	P.ordem as OrdemP,   
	P.ativo,   
	C.Ordem as OrdemC,   
	S.Ordem as OrdemS 
	FROM 
		GC_Produtos P 
		INNER JOIN GC_ProdutosCategorias C ON 
			P.CodCategoria = C.CodCategoria 
		LEFT JOIN GC_ProdutosSubCategorias S ON 
			P.CodSubCategoria = S.CodSubCategoria 
	WHERE P.ativo = 1;
) R;

O primeiro retorna os resultados e o segundo o total

 

o erro quando executa a página é esse:

 

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '(ORDER BY B.OrdemC, B.OrdemS, B.OrdemP) AS Pagina, B.* FROM ( SELECT P.CodProd' at line 1

 

Creio que seja o row_number!!

 

Alguem poderia ajudar?

 

Att.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Boa tarde!

Desculpe reviver o topico , mas surgiu o mesmo problema pra mim!

 

Eu tenho um select do sqlserver pronto pra paginaçao, porém preciso converter pra mysql

Alguem saberia indicar como fazer ?

 

o select é esse:

SELECT * FROM (   
	SELECT ROW_NUMBER() OVER(ORDER BY B.OrdemC, B.OrdemS, B.OrdemP) AS Pagina, B.* FROM (
		SELECT   
		P.CodProduto,   
		P.CodCategoria,   
		C.Titulo as TituloCategoria,   
		ifNull(P.CodSubCategoria, 0),   
		ifNull(S.Titulo, '') as TituloSubCategoria,   
		P.Titulo as Titulo,   
		P.Subtitulo,   
		P.descricao,   
		P.ordem as OrdemP,   
		P.ativo,   
		C.Ordem as OrdemC,   
		S.Ordem as OrdemS 
		FROM 
			GC_Produtos P 
			INNER JOIN GC_ProdutosCategorias C ON 
				P.CodCategoria = C.CodCategoria 
			LEFT JOIN GC_ProdutosSubCategorias S ON 
			P.CodSubCategoria = S.CodSubCategoria 
		WHERE P.ativo = 1;   
	) B 
) R 
WHERE R.Pagina 
BETWEEN @PaginaInicial AND @PaginaFinal 
ORDER BY R.Pagina; 

SELECT COUNT(1) AS Total FROM ( 
	SELECT   
	P.CodProduto,   
	P.CodCategoria,   
	C.Titulo as TituloCategoria,   
	ifNull(P.CodSubCategoria, 0),   
	ifNull(S.Titulo, '') as TituloSubCategoria,   
	P.Titulo as Titulo,   
	P.Subtitulo,   
	P.descricao,   
	P.ordem as OrdemP,   
	P.ativo,   
	C.Ordem as OrdemC,   
	S.Ordem as OrdemS 
	FROM 
		GC_Produtos P 
		INNER JOIN GC_ProdutosCategorias C ON 
			P.CodCategoria = C.CodCategoria 
		LEFT JOIN GC_ProdutosSubCategorias S ON 
			P.CodSubCategoria = S.CodSubCategoria 
	WHERE P.ativo = 1;
) R;

O primeiro retorna os resultados e o segundo o total

 

o erro quando executa a página é esse:

 

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '(ORDER BY B.OrdemC, B.OrdemS, B.OrdemP) AS Pagina, B.* FROM ( SELECT P.CodProd' at line 1

 

Creio que seja o row_number!!

 

Alguem poderia ajudar?

 

Att.

 

Fala pessoal,

 

De mto tentar conseguir fazer!!

 

troquei a parte:

ROW_NUMBER() OVER(ORDER BY B.OrdemC, B.OrdemS, B.OrdemP)

por:

@row := @row + 1

mas precisa declarar a variavel @row antes:

 

set @row:=0;

Como eu estou usando c# + mysql, precisa incluir na connectionString, o parametro Allow User Variables=True:

Database=testdb;Data Source=localhost;User Id=root;Password=hello;Allow User Variables=True

Se alguem precisar esta ai!

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.