Beraldo 864 Denunciar post Postado Julho 13, 2012 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
advaldomesquita 93 Denunciar post Postado Julho 13, 2012 Subselect pelo ID_PAI? Vão me estrangular por falar isso. Compartilhar este post Link para o post Compartilhar em outros sites
NaPraia 12 Denunciar post Postado Julho 13, 2012 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
NaPraia 12 Denunciar post Postado Julho 13, 2012 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
advaldomesquita 93 Denunciar post Postado Julho 13, 2012 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
Beraldo 864 Denunciar post Postado Julho 13, 2012 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
Motta 645 Denunciar post Postado Julho 13, 2012 http://forum.imasters.com.br/topic/459120-select-complexo-de-amigos/page__p__1817840__hl__%2Bhierarquica+%2B__fromsearch__1#entry1817840 http://forum.imasters.com.br/topic/342289-listagem-de-produtos-por-categoria-e-subcategoria/page__p__1278390__hl__%2Bhierarquica+%2B__fromsearch__1#entry1278390 veja se ajuda. Compartilhar este post Link para o post Compartilhar em outros sites
Beraldo 864 Denunciar post Postado Julho 14, 2012 Obrigado também pelas dicas, Motta! :thumbsup: "hierárqiuica" era a palavra que faltava para eu encontrar resultados decentes na busca Compartilhar este post Link para o post Compartilhar em outros sites
Andrey Knupp Vital 136 Denunciar post Postado Julho 14, 2012 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
s4muk4 0 Denunciar post Postado Março 28, 2013 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 mysqlAlguem 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
s4muk4 0 Denunciar post Postado Março 28, 2013 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