Conceitos básicos de junção

Usando junções, é possível recuperar dados de duas ou mais tabelas com base em relações lógicas entre as tabelas. Junções indicam como Microsoft SQL Server deveriam usar dados de uma tabela para selecionar as linhas em outra tabela.

Uma condição de junção define o modo como duas tabelas são relacionadas em uma consulta por:

  • Especificando a coluna de cada tabela a ser usada para a junção. Uma condição de junção típica especifica uma chave estrangeira de uma tabela e sua chave associada na outra tabela.

  • Especificando um operador lógico (por exemplo, = ou <>) a ser usado na comparação de valores das colunas.

Junções internas podem ser especificadas em cláusulas FROM ou WHERE. Junções externas só podem ser especificadas na cláusula FROM. As condições de junção combinam os critérios de pesquisa WHERE e HAVING para controlar as linhas selecionadas das tabelas base referenciadas na cláusula FROM.

Especificar as condições de junção na cláusula FROM, ajuda a separá-las de qualquer outro critério de pesquisa que possa ser especificado em uma cláusula WHERE e é o método recomendado para a especificação de junções. Uma sintaxe de junção de cláusula ISO FROM simplificada é:

FROM first_table join_type second_table[ON (join_condition)]

join_type especifica que tipo de junção é executada: uma junção interna, externa ou cruzada. join_condition define o predicado a ser avaliado para cada par de linhas unidas. O exemplo a seguir é de uma especificação de junção de cláusula FROM:

FROM Purchasing.ProductVendor JOIN Purchasing.Vendor
     ON (ProductVendor.BusinessEntityID = Vendor.BusinessEntityID)

O exemplo a seguir é uma instrução SELECT simples que usa esta junção:

SELECT ProductID, Purchasing.Vendor.BusinessEntityID, Name
FROM Purchasing.ProductVendor JOIN Purchasing.Vendor
    ON (Purchasing.ProductVendor.BusinessEntityID = Purchasing.Vendor.BusinessEntityID)
WHERE StandardPrice > $10
  AND Name LIKE N'F%'
GO

A seleção retorna o produto e as informações de fornecedor para qualquer combinação de partes fornecidas por uma empresa cujo nome começa com a letra F e o preço do produto é maior que $10.

Quando várias tabelas são referenciadas em uma única consulta, todas as referências de coluna devem ser inequívocas. No exemplo anterior, ambas as tabelas de ProductVendor e Vendor têm uma coluna nomeada BusinessEntityID. Qualquer nome de coluna que seja duplicado entre duas ou mais tabelas referenciadas na consulta deve ser qualificado com o nome da tabela. Todas as referências para as colunas Vendor no exemplo estão qualificadas.

Quando um nome de coluna não está duplicado em duas ou mais tabelas usadas na consulta, a referências a ele não precisam ser qualificadas com o nome da tabela. Isso é mostrado no exemplo anterior. Por vezes a instrução SELECT é difícil de compreender, pois não há nada que indique a tabela que forneceu cada coluna. A legibilidade da consulta será aprimorada se todas as colunas estiverem qualificadas com seus nomes de tabela. A legibilidade é aperfeiçoada se aliases de tabela são usados, principalmente quando os nomes de tabelas precisam ser qualificados com nomes de proprietários e de banco de dados. O exemplo seguinte é o mesmo, exceto que aliases de tabela foram atribuídos e as colunas foram qualificadas com aliases de tabela para aperfeiçoar a legibilidade:

SELECT pv.ProductID, v.BusinessEntityID, v.Name
FROM Purchasing.ProductVendor AS pv 
JOIN Purchasing.Vendor AS v
    ON (pv.BusinessEntityID = v.BusinessEntityID)
WHERE StandardPrice > $10
    AND Name LIKE N'F%';

Os exemplos anteriores especificaram as condições de junção na cláusula FROM, que é o método preferencial. A seguinte consulta contém a mesma condição de junção especificada na cláusula WHERE:

SELECT pv.ProductID, v.BusinessEntityID, v.Name
FROM Purchasing.ProductVendor AS pv, Purchasing.Vendor AS v
WHERE pv.VendorID = v.VendorID
    AND StandardPrice > $10
    AND Name LIKE N'F%';

A lista de seleção para uma junção pode fazer referência a todas as colunas nas tabelas unidas ou a qualquer subconjunto de colunas. A lista de seleção não precisa conter colunas de todas as tabelas na junção. Por exemplo, em uma junção de três tabelas, somente uma tabela pode ser usada para ligar uma das tabelas à terceira e, nenhuma das colunas da tabela do meio, precisa ser referenciada na lista de seleção.

Embora as condições de junção tenham comparações de igualdade (=), outros operadores relacionais ou de comparação podem ser especificados, como também outros predicados. Para obter mais informações, consulte Usando operadores em expressões e WHERE (Transact-SQL).

Quando SQL Server processa junções, o mecanismo de consulta escolhe o método mais eficaz (entre várias possibilidades) de processamento da junção. A execução física de várias junções pode usar muitas otimizações diferentes e portanto não pode ser prevista de maneira confiável.

Colunas usadas em uma condição de junção não precisam ter o mesmo nome ou ter o mesmo tipo de dados. Entretanto, se os tipos de dados não forem idênticos, eles devem ser compatíveis, ou do tipo que o SQL Server possa converter implicitamente. Se o tipo de dados não puder ser convertido implicitamente, a condição de junção deverá converter explicitamente o tipo de dados usando a função CAST. Para obter mais informações sobre conversões implícitas e explícitas, consulte Conversão de tipo de dados (Mecanismo de Banco de Dados).

A maioria das consultas que usam uma junção pode ser regravada usando uma subconsulta (uma consulta aninhada dentro de outra consulta) e a maioria das subconsultas pode ser regravada como junções. Para obter mais informações sobre subconsultas, consulte Noções básicas sobre subconsultas.

ObservaçãoObservação

Tabelas não podem ser unidas diretamente em ntext, text ou colunas image. No entanto, as tabelas podem ser unidas indiretamente em ntext, text ou colunas image usando SUBSTRING. Por exemplo, SELECT * FROM t1 JOIN t2 ON SUBSTRING(t1.textcolumn, 1, 20) = SUBSTRING(t2.textcolumn, 1, 20) realiza uma junção interna de duas tabelas nos primeiros 20 caracteres de cada coluna de texto nas tabelas t1 e t2. Além disso, outra possibilidade de comparação das colunas ntext ou text de duas tabelas é comparar o comprimento das colunas com a cláusula WHERE, por exemplo: WHERE DATALENGTH(p1.pr_info) = DATALENGTH(p2.pr_info)