Ir para conteúdo

Arquivado

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

willwalker

[Resolvido] Categorias com Hierarquias de avo, pai, filho e neto.

Recommended Posts

Tenho um GRANDE problema:

 

Tenho uma tabela de categorias e outra de produtos. As categorias são relacionadas pelo Field pai e eu tenho que buscar as categorias cadastradas nos produtos no Field categorias.

 

O problema é que essas categorias podem ser, avo, pai, filho ou neto (Hierarquia das categorias) . E o meu supervisor me disse para fazer assim a query:

 

SELECT
(SELECT avo.pai FROM categorias AS avo WHERE avo.id = (SELECT pai.pai FROM categorias AS pai WHERE pai.id = (SELECT filho.pai FROM categorias AS filho WHERE filho.id = neto.id))) AS ida,
(SELECT avo.categoria_en FROM categorias AS avo WHERE avo.id = (SELECT avo.pai FROM categorias AS avo WHERE avo.id = (SELECT pai.pai FROM categorias AS pai WHERE pai.id = (SELECT filho.pai FROM categorias AS filho WHERE filho.id = neto.id)))) AS nna,
(SELECT pai.pai FROM categorias AS pai WHERE pai.id = (SELECT filho.pai FROM categorias AS filho WHERE filho.id = neto.id)) AS idp,
(SELECT pai.categoria_en FROM categorias AS pai WHERE pai.id = (SELECT pai.pai FROM categorias AS pai WHERE pai.id = (SELECT filho.pai FROM categorias AS filho WHERE filho.id = neto.id))) AS nnp,
(SELECT filho.pai FROM categorias AS filho WHERE filho.id = neto.id) AS idf,
(SELECT filho.categoria_en FROM categorias AS filho WHERE filho.id = (SELECT filho.pai FROM categorias AS filho WHERE filho.id = neto.id)) AS nnf,
neto.id AS idn,
neto.categoria_en AS nnn
FROM
categorias AS netoORDER BY nna, nnp, nnf, nnn

 

Eu acho que essa query é errada, mas eu nomeei cada sub query para que vocês possam entender.

 

A hierarquia é a seguinte:

Listo todas as categorias, depois seleciono do ultimo para o primeiro de acordo com o pai. Se eu quero pegar o id do avo, faço um select onde pega o id da categoria que o pai dela é igual ao id onde o pai é igual ao id e o pai é igual ao id da categoria neto.

 

Conseguem entender o tamanho da buxa ? E ainda por cima tenho que comparar os ids das categorias de produtos onte pode ter avo, pai, filho e neto e tambem fazer um count dessas categorias. Resumindo... ESTOU LASCADO. Alguem conseguiu entender e pode me ajudar ?

 

Um amigo me ajudou e eu refiz a query:

 

SELECT
avo.id AS ida,
avo.categoria_en AS nna,
pai.id AS idp,
pai.categoria_en AS nnp,
filho.id AS idf,
filho.categoria_en AS nnf,
neto.id AS idn,
neto.categoria_en AS nnn
FROM
categorias AS avo
LEFT JOIN categorias AS pai ON avo.id = pai.pai
LEFT JOIN categorias AS filho ON pai.id = filho.pai
LEFT JOIN categorias AS neto ON filho.id = neto.pai
WHERE
avo.pai = '0'
ORDER BY nna, nnp, nnf, nnn

 

 

Me trouxe certo e agora eu preciso relacionar as categorias dos produtos e fazer um count, que pode conter o id do avo, pai, filho, ou neto, exemplo:

 

102, 55, 20, ou 55, 102, 20, - Pelo menos o padrão das categorias é o id da categoria com um espaço e uma virgula. (id ,).

 

Alguem sabe fazer isso ?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Resolvi mais uma vez sozinho. dry.gif

 

A solução foi:

 

SELECT
neto.pai AS pai_neto,
neto.id AS idn,
neto.categoria_en AS nnn,
IF(neto.pai=0, neto.pai, filho.pai) AS pai_filho,
IF(neto.pai=0, neto.id, filho.id) AS idf,
IF(neto.pai=0, neto.categoria_en, filho.categoria_en) AS nnf,
IF(neto.pai=0, neto.pai, IF(filho.pai=0, filho.pai, pai.pai)) AS pai_pai,
IF(neto.pai=0, neto.id, IF(filho.pai=0, filho.id, pai.id)) AS idp,
IF(neto.pai=0, neto.categoria_en, IF(filho.pai=0, filho.categoria_en, pai.categoria_en)) AS nnp,
IF(neto.pai=0, neto.pai, IF(filho.pai=0, filho.pai, IF(pai.pai=0, pai.pai, avo.pai))) AS pai_avo,
IF(neto.pai=0, neto.id, IF(filho.pai=0, filho.id, IF(pai.pai=0, pai.id, avo.id))) AS ida,
IF(neto.pai=0, neto.categoria_en, IF(filho.pai=0, filho.categoria_en, IF(pai.pai=0, pai.categoria_en, avo.categoria_en))) AS nna,
pd.id,
pd.titulo_en AS titulo,
pd.foto AS foto
FROM
produtos AS pd
LEFT OUTER JOIN categorias AS neto ON pd.categorias = neto.id
LEFT OUTER JOIN categorias AS filho ON neto.pai = filho.id
LEFT OUTER JOIN categorias AS pai ON filho.pai = pai.id
LEFT OUTER JOIN categorias AS avo ON pai.pai = avo.id
WHERE
neto.id <> '' AND
neto.categoria_en <> '' AND
neto.pai <> '99999999' AND
pd.uid = '1' AND
pd.valido = '1'ORDER BY titulo ASC

 

 

Pego as categorias dos produtos, trago a categoria de acordo com o seu pai, depois fiz um if para popular as celulas que irão ficar vazias, porque se o pai da categoria for o avo, não haverá nenhuma outra categoria relacionada a ela.

 

A query demora 1s. O legal seria abaixar isso para 0.35s, mas por enquanto está bom para funcionar, quando tiver tempo dou uma melhorada, mas acho que não tem como melhorar o tempo dessa query, talvez indexando alguma coisa para melhorar o tempo de consulta.

 

Abraços!

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.