No post anterior faltou acrescentar alguns detalhes sobre LEFT JOINS que coloco agora.
Use LEFT JOIN quando:
A maneira de restringir (condições de busca) também é semelhante ao INNER JOIN.
SELECT [TABELA1.COLUNAS] ...
,[TABELA2.COLUNAS...]
, ...
,[TABELAn.COLUNAS...]
FROM [TABELA1], [TABELA2], ..., [TABELAn]
O problema aqui é que este tipo de JOIN traz como resultado, caso nenhum filtro seja especificado na cláusula WHERE, o produto cartesiano dos registros de todas as tabelas, ou seja para cada registro na TABELA1, todos os registros da TABELA2 até a “TABELAn” são trazidos.
Se fizermos o primeiro exemplo de INNER JOIN deste jeito onde PERSON.PERSON tem 19.972 registros e HUMANRESOURCES.EMPLOYEE. 290, o número de registros recuperados será 19.972 x 290 = 5.791.880. A consulta (execute por sua conta e risco...) fica assim:
select p.FirstName + ' ' + p.LastName as CompleteName
,hre.JobTitle
,hre.BirthDate
from person.person p, HumanResources.Employee hre
select p.FirstName + ' ' + p.LastName as CompleteName
,hre.JobTitle
,hre.BirthDate
from person.person p, HumanResources.Employee hre
where p.BusinessEntityID=hre.BusinessEntityID
Nesta tabela temos três colunas:
Não existe um limite de quantas auto referências podem ser feitas, deve-se apenas, prestar atenção para não criar consultas recursivas e deixar o banco em loop causando um lock desnecessário.
O SQL server tem um tipo de coluna – HIERARCHID – próprio para armazenar dados do tipo como vimos acima (hierárquicos), embora, a maneira mais direta se se fazer isto seja como vimos no exemplo.
Terminamos por aqui a segunda parte da série de treinamentos em SQL referente às JOINS. A próxima etapa será falar sobre os filtros e a cláusula WHERE. Até lá.
Use LEFT JOIN quando:
- O objetivo for listar todos os registros de uma tabela e mostrar colunas de outra havendo ou não correspondências.
- Precisar saber se existem registros filhes de uma tabela pai em uma (ou várias) filho.
Não use para fazer filtros, conforme foi demonstrado com INNER JOIN.
A maneira de restringir (condições de busca) também é semelhante ao INNER JOIN.
Uma questão sobre desempenho
O desempenho com LEFT JOIN é melhor do que com INNER JOIN, porém, pode ser que em alguns casos seja necessário usar mesmo o INNER.
Usando CROSS JOIN (na verdade é melhor nem usar)
Este tipo de JOIN está aqui meramente para exemplo pois causa muitos problemas. Consiste em vez de usar o termo JOIN, colocar as tabelas relacionadas na cláusula FROM.
SELECT [TABELA1.COLUNAS] ...
,[TABELA2.COLUNAS...]
, ...
,[TABELAn.COLUNAS...]
FROM [TABELA1], [TABELA2], ..., [TABELAn]
O problema aqui é que este tipo de JOIN traz como resultado, caso nenhum filtro seja especificado na cláusula WHERE, o produto cartesiano dos registros de todas as tabelas, ou seja para cada registro na TABELA1, todos os registros da TABELA2 até a “TABELAn” são trazidos.
Se fizermos o primeiro exemplo de INNER JOIN deste jeito onde PERSON.PERSON tem 19.972 registros e HUMANRESOURCES.EMPLOYEE. 290, o número de registros recuperados será 19.972 x 290 = 5.791.880. A consulta (execute por sua conta e risco...) fica assim:
select p.FirstName + ' ' + p.LastName as CompleteName
,hre.JobTitle
,hre.BirthDate
from person.person p, HumanResources.Employee hre
Uma forma de se evitar o produto cartesiano é através da cláusula
WHERE:
select p.FirstName + ' ' + p.LastName as CompleteName
,hre.JobTitle
,hre.BirthDate
from person.person p, HumanResources.Employee hre
where p.BusinessEntityID=hre.BusinessEntityID
O que nesse caso, vai ser equivalente à consulta com INNER JOIN.
Se uma terceira tabela for incluída, digamos, com cem registros, a conta ficará 19.972 x 290 x 100 = 579.188.000, logo, dá para perceber o tamanho do estrago e a dica aqui é NÃO USE ISSO DE JEITO NENHUM. A possibilidade de estragos e problemas com desempenho é muito grande.
Como o próprio nome diz, consiste em fazer referência a própria tabela. O que pode parecer muito esquisito inicialmente, mas, tem sua aplicação principalmente para armazenamento e representação de dados hierárquicos, como, por exemplo: Se uma terceira tabela for incluída, digamos, com cem registros, a conta ficará 19.972 x 290 x 100 = 579.188.000, logo, dá para perceber o tamanho do estrago e a dica aqui é NÃO USE ISSO DE JEITO NENHUM. A possibilidade de estragos e problemas com desempenho é muito grande.
SELF JOIN e algo um pouco esquisito - recursão
- Árvore de pastas e subpastas
- Funcionário e seu encarregado – que na prática é também um funcionário
- Departamento e departamentos afiliados
Nesta tabela temos três colunas:
- FolderId: chave primária para cada pasta
- ParentFolderId: chave estrangeira e Id da pasta que está um nível acima, ou, pasta “pai”, se preferir.
- Name: nome da pasta
select df0.Name as ParantFolder
,df1.Name as FolderName
from documents.folders as df1
left join documents.folders as df0 on
df0.FolderId=df1.ParentFolderId;
,df1.Name as FolderName
from documents.folders as df1
left join documents.folders as df0 on
df0.FolderId=df1.ParentFolderId;
Não existe um limite de quantas auto referências podem ser feitas, deve-se apenas, prestar atenção para não criar consultas recursivas e deixar o banco em loop causando um lock desnecessário.
O SQL server tem um tipo de coluna – HIERARCHID – próprio para armazenar dados do tipo como vimos acima (hierárquicos), embora, a maneira mais direta se se fazer isto seja como vimos no exemplo.
Terminamos por aqui a segunda parte da série de treinamentos em SQL referente às JOINS. A próxima etapa será falar sobre os filtros e a cláusula WHERE. Até lá.