Compreender conceitos e sintaxe de junções

Concluído

O método mais fundamental e comum de combinar dados de várias tabelas é usar uma operação JOIN. Algumas pessoas pensam em JOIN como uma cláusula separada em uma instrução SELECT, mas outras pensam nela como parte da cláusula FROM. Este módulo irá considerá-lo principalmente como parte da cláusula FROM. Neste módulo, descobriremos como a cláusula FROM em uma instrução T-SQL SELECT cria tabelas virtuais intermediárias que serão consumidas por fases posteriores da consulta.

A Cláusula FROM e as Tabelas Virtuais

Se você aprendeu sobre a ordem lógica das operações que são executadas quando o SQL Server processa uma consulta, viu que a cláusula FROM de uma instrução SELECT é a primeira cláusula a ser processada. Esta cláusula determina qual tabela ou tabelas serão a origem das linhas para a consulta. O FROM pode fazer referência a uma única tabela ou reunir várias tabelas como a fonte de dados para sua consulta. Você pode pensar na cláusula FROM como criar e preencher uma tabela virtual. Esta tabela virtual conterá a saída da cláusula FROM e será usada por cláusulas da instrução SELECT que são aplicadas posteriormente, como a cláusula WHERE. À medida que você adiciona funcionalidades extras, como operadores de junção, a uma cláusula FROM, será útil pensar na finalidade dos elementos da cláusula FROM como adicionar linhas ou remover linhas da tabela virtual.

A tabela virtual criada por uma cláusula FROM é apenas uma entidade lógica. No SQL Server, nenhuma tabela física é criada, seja persistente ou temporária, para armazenar os resultados da cláusula FROM, pois ela é passada para a cláusula WHERE ou outras partes da consulta.

A tabela virtual criada pela cláusula FROM contém dados de todas as tabelas associadas. Pode ser útil pensar nos resultados como conjuntos e conceituar os resultados de junção como um diagrama de Venn.

A Venn diagram showing the set of an Employee table joined to a SalesOrder table

Ao longo de sua história, a linguagem T-SQL se expandiu para refletir as mudanças nos padrões do American National Standards Institute (ANSI) para a linguagem SQL. Um dos lugares mais notáveis onde essas alterações são visíveis é na sintaxe para junções em uma cláusula FROM. No padrão ANSI SQL-89, as junções foram especificadas incluindo várias tabelas na cláusula FROM em uma lista separada por vírgula. Qualquer filtragem para determinar quais linhas incluir foi executada na cláusula WHERE, da seguinte forma:

SELECT p.ProductID, m.Name AS Model, p.Name AS Product
FROM SalesLT.Product AS p, SalesLT.ProductModel AS m
WHERE p.ProductModelID = m.ProductModelID;

Essa sintaxe ainda é suportada pelo SQL Server, mas devido à complexidade de representar os filtros para junções complexas, ela não é recomendada. Além disso, se uma cláusula WHERE for omitida acidentalmente, as junções no estilo ANSI SQL-89 podem facilmente se tornar produtos cartesianos e retornar um número excessivo de linhas de resultados, causando problemas de desempenho e possivelmente resultados incorretos.

Ao aprender sobre como escrever consultas de várias tabelas em T-SQL, é importante entender o conceito de produtos cartesianos. Em matemática, um produto cartesiano é o produto de dois conjuntos. O produto de um conjunto de dois elementos e um conjunto de seis elementos é um conjunto de 12 elementos, ou 6 x 2. Cada elemento de um conjunto é combinado com cada elemento do outro conjunto. No exemplo abaixo, temos um conjunto de nomes com dois elementos e um conjunto de produtos com três elementos. O produto cartesiano combina todos os nomes com cada produto produzindo seis elementos.

Cartesian product

Em bancos de dados, um produto cartesiano é o resultado da combinação de cada linha de uma tabela para cada linha de outra tabela. O produto de uma tabela com 10 linhas e uma tabela com 100 linhas é um conjunto de resultados com 1.000 linhas. O resultado subjacente de uma operação JOIN é um produto cartesiano, mas para a maioria das consultas T-SQL, um produto cartesiano não é o resultado desejado. No T-SQL, um produto cartesiano ocorre quando duas tabelas de entrada são unidas sem considerar quaisquer relações entre elas. Sem informações sobre relacionamentos, o processador de consultas do SQL Server retornará todas as combinações possíveis de linhas. Embora esse resultado possa ter algumas aplicações práticas, como a geração de dados de teste, normalmente não é útil e pode ter implicações graves no desempenho.

Com o advento do padrão ANSI SQL-92, o suporte para as palavras-chave JOIN e ON cláusulas foi adicionado. O T-SQL também suporta esta sintaxe. As junções são representadas na cláusula FROM usando o operador JOIN apropriado. A relação lógica entre as tabelas, que se torna um predicado de filtro, é especificada na cláusula ON.

O exemplo a seguir reafirma a consulta anterior com a sintaxe mais recente:

SELECT p.ProductID, m.Name AS Model, p.Name AS Product
FROM SalesLT.Product AS p
JOIN SalesLT.ProductModel AS m
    ON p.ProductModelID = m.ProductModelID;

Nota

A sintaxe ANSI SQL-92 torna mais difícil criar produtos cartesianos acidentais. Depois que a palavra-chave JOIN for adicionada, um erro de sintaxe será gerado se uma cláusula ON estiver faltando, a menos que a JOIN seja especificada como CROSS JOIN.