Usar junções internas

Concluído

O tipo mais frequente de JOIN nas consultas T-SQL é a INNER JOIN. As junções internas são usadas para resolver muitos problemas comuns de negócios, especialmente em ambientes de banco de dados altamente normalizados. Muitas vezes, para recuperar dados armazenados em várias tabelas, você vai precisar combiná-los por meio de consultas de INNER JOIN. Uma INNER JOIN inicia sua fase de processamento lógico como um produto cartesiano, que é filtrado para remover as linhas que não correspondam ao predicado.

Processar uma INNER JOIN

Vamos examinar as etapas pelas quais o SQL Server vai processar logicamente uma consulta JOIN. Os números de linha no seguinte exemplo hipotético foram adicionados para fins de clareza:

1) SELECT emp.FirstName, ord.Amount
2) FROM HR.Employee AS emp 
3) JOIN Sales.SalesOrder AS ord
4)      ON emp.EmployeeID = ord.EmployeeID;

Como você deve saber, a cláusula FROM vai ser processada antes da cláusula SELECT. Vamos acompanhar o processamento, começando com a linha 2:

  • A cláusula FROM especifica a tabela HR.Employee como uma das tabelas de entrada, dando a ela o alias emp.
  • O operador JOIN na linha 3 reflete o uso de uma INNER JOIN (o tipo padrão no T-SQL) e especifica Sales.SalesOrder como a outra tabela de entrada, que tem um alias de ord.
  • O SQL Server vai executar uma junção cartesiana lógica nessas tabelas e passar os resultados como uma tabela virtual para a próxima etapa. (O processamento físico da consulta pode não realizar a operação do produto cartesiano, dependendo das decisões do otimizador. Mas pode ser útil imaginar o produto cartesiano sendo criado.)
  • Usando a cláusula ON, o SQL Server vai filtrar a tabela virtual, mantendo apenas as linhas em que um valor EmployeeID da tabela emp corresponde a um EmployeeID da tabela ord.
  • As linhas restantes permanecem na tabela virtual e são entregues para a próxima etapa na instrução SELECT. Neste exemplo, a tabela virtual é processada em seguida pela cláusula SELECT e as duas colunas especificadas são retornadas ao aplicativo cliente.

O resultado ao final da consulta é uma lista de funcionários e os valores dos seus pedidos. Os funcionários que não têm nenhum pedido associado foram filtrados pela cláusula ON, assim como os pedidos cuja EmployeeID não corresponde a nenhuma entrada na tabela RH.Employee.

A Venn diagram showing the matching members of the Employee and SalesOrder sets

Sintaxe INNER JOIN

Uma INNER JOIN é o tipo padrão de cláusula JOIN e a palavra-chave INNER opcional é implícita na cláusula JOIN. Ao combinar e corresponder tipos de junção, pode ser útil especificar explicitamente o tipo da junção, conforme mostrado neste exemplo hipotético:

SELECT emp.FirstName, ord.Amount
FROM HR.Employee AS emp 
INNER JOIN Sales.SalesOrder AS ord
    ON emp.EmployeeID = ord.EmployeeID;

Ao gravar consultas usando junções internas, considere as seguintes diretrizes:

  • Os aliases de tabela são preferenciais, não apenas para a lista SELECT, mas também para gravar a cláusula ON.
  • As junções internas podem ser executadas em uma única coluna correspondente, como uma OrderID, ou em vários atributos correspondentes, como a combinação de OrderID e de ProductID. A junções que especificam várias colunas correspondentes são chamadas de junções compostas.
  • A ordem na qual as tabelas são listadas na cláusula FROM para uma INNER JOIN não é relevante para o otimizador do SQL Server. Conceitualmente, as junções são avaliadas da esquerda para a direita.
  • Use a palavra-chave JOIN uma vez para cada par de tabelas unidas na lista FROM. Para uma consulta de duas tabelas, especifique uma junção. Para uma consulta de três tabelas, use JOIN duas vezes: uma vez entre as duas primeiras tabelas e de novo entre a saída de JOIN das duas primeiras tabelas e a terceira tabela.

Exemplos de INNER JOIN

O seguinte exemplo hipotético executa uma junção em uma única coluna correspondente, relacionando o ProductModelID da tabela Production.Product ao ProductModelID da tabela Production.ProductModel:

SELECT p.ProductID, m.Name AS Model, p.Name AS Product
FROM Production.Product AS p
INNER JOIN Production.ProductModel AS m
    ON p.ProductModelID = m.ProductModelID
ORDER BY p.ProductID;

O próximo exemplo mostra como uma junção interna pode ser estendida para incluir mais de duas tabelas. A tabela Sales.SalesOrderDetail é unida à saída de JOIN entre Production.Product e Production.ProductModel. Cada instância de JOIN/ON faz o rastreamento e a filtragem da tabela de saída virtual. O otimizador de consulta do SQL Server determina a ordem na qual as junções e a filtragem vão ser executadas.

SELECT od.SalesOrderID, m.Name AS Model, p.Name AS ProductName, od.OrderQty
FROM Production.Product AS p
INNER JOIN Production.ProductModel AS m
    ON p.ProductModelID = m.ProductModelID
INNER JOIN Sales.SalesOrderDetail AS od
    ON p.ProductID = od.ProductID
ORDER BY od.SalesOrderID;