Recentemente eu fiz uma pergunta em dba.stackexchange a pergunta era sobre hierarquia de dados em sql e um cara chamado chris allen respondeu a pergunta e eu realmente adorei, mas quando tento entender muito mais essa consulta, fico confuso.
Aqui está a consulta:
Res_id Res_name Man_id
1 sam 3
2 Biju 4
3 adrian Null
4 Helen 3
5 Micah 4
select
level1.res_name as level1,
level2.res_name as level2,
level3.res_name as level3,
level4.res_name as level4,
level5.res_name as level5
from resource as level1
left join resource as level2 on level1.res_id=level2.man_id
left join resource as level3 on level2.res_id=level3.man_id
left join resource as level4 on level3.res_id=level4.man_id
left join resource as level5 on level4.res_id=level5.man_id
where isnull(level1.man_id,0)=0
Fiz várias abordagens de crack e foi em vão. Acho que estou perdendo algo, bem, minhas descobertas são dadas abaixo
- Primeiro ele nomeou quatro colunas como cada nível 1,2,3 etc.
- Cada vez que ele saiu, entrou na mesma mesa 4 vezes, cada um com pseudônimos diferentes
- Ao dar condição em cada junção, a tabela está sendo alterada para o próximo nível
- Onde condição para especificar o gerente
A parte que não entendi é a junção que ele fez, embora eu saiba o uso da junção esquerda, onde obteremos as colunas da tabela esquerda e da direita, se nenhuma correspondência for encontrada, será NULL. da junção acontecendo aqui ou alguma compreensão das junções em profundidade neste cenário específico. Se a pergunta não couber aqui, irei excluí-la. Eu também perguntei o mesmo na pergunta que postei, mas não houve resposta, por isso estou colocando uma nova pergunta
Tente esta consulta sem as junções primeiro:
Isso retorna as linhas onde
man_id
não está referenciando nada. Em outras palavras, isso retorna apenas os gerentes de nível mais alto. Para o seu exemplo particular, funciona assim:a cláusula FROM retorna a tabela inteira:
a cláusula WHERE deixa apenas uma linha:
por fim, o SELECT tira dele apenas uma coluna:
Adicionando uma autojunção como na consulta de Chris,
dá-lhe todos os subordinados diretos do gerente de nível superior. Mais especificamente, a união resulta no seguinte conjunto de linhas:
A cláusula WHERE filtra para apenas isso:
E finalmente a cláusula SELECT retorna apenas os nomes:
Da mesma forma, adicionando mais uma junção, assim:
traz o próximo nível de subordinados:
este é o resultado da junção da terceira instância da tabela com os resultados da primeira junção:
(Eu encurtei os aliases da tabela por conveniência:
1
significalevel1
,2
forlevel2
, e3
forlevel3
)isto é o que resta após o filtro WHERE:
e é isso que SELECT extrai do acima e devolve:
O mesmo continua para o resto das uniões. Com o seu exemplo, no entanto, não haverá mais linhas, pois a hierarquia na tabela não vai além de dois níveis. Consequentemente, as outras duas colunas na consulta original de Chris,
level4
elevel5
, retornarão NULLs:Se a suposição de Chris de que quatro junções devem ser suficientes para a maioria dos casos não funcionar para o seu caso específico (e não me refiro ao exemplo simples em sua pergunta, é claro), você pode incluir mais autojunções usando o mesmo padrão.