Entender conceitos e sintaxes de junções

Concluído

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

A Cláusula FROM e as Tabelas Virtuais

Se você aprendeu sobre a ordem lógica das operações executadas quando o SQL Server processa uma consulta, você sabe que a cláusula FROM de uma instrução SELECT é a primeira cláusula a ser processada. Essa cláusula determina quais tabelas vão ser a fonte das linhas da consulta. A cláusula FROM pode fazer referência a uma tabela ou reunir várias tabelas como a fonte de dados para a consulta. Você pode considerar a cláusula FROM como a criação e o preenchimento de uma tabela virtual. Essa tabela virtual vai manter a saída da cláusula FROM e vai ser usada pelas cláusulas da instrução SELECT que são aplicadas posteriormente, como a cláusula WHERE. À medida que funcionalidades extras, como operadores de junção, são adicionadas a uma cláusula FROM, é útil considerar a finalidade de adição ou de remoção de linhas da tabela virtual para os elementos da cláusula FROM.

A tabela virtual criada por uma cláusula FROM é somente uma entidade lógica. No SQL Server, nenhuma tabela física é criada, seja persistente ou temporária, para manter os resultados da cláusula FROM, pois eles são passados para a cláusula WHERE ou para outras partes da consulta.

A tabela virtual criada pela cláusula FROM contém os dados de todas as tabelas juntas. É útil considerar os resultados como conjuntos e conceituar os resultados da junção como um diagrama de Venn.

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

Ao longo do seu histórico, a linguagem T-SQL expandiu para refletir as alterações do padrão ANSI (American National Standards Institute) para a linguagem SQL. Um dos locais mais importantes em que 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 eram especificadas incluindo várias tabelas na cláusula FROM em uma lista separada por vírgulas. As filtragens para determinar as linhas a serem incluídas eram executadas na cláusula WHERE, desta 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 tem suporte do SQL Server, mas não é recomendada devido à complexidade para representar os filtros para junções complexas. 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 resultado, causando problemas de desempenho e resultados possivelmente incorretos.

Ao aprender a gravar consultas de várias tabelas em T-SQL, é importante entender o conceito de produtos cartesianos. Em matemática, um produto cartesiano é um produto de dois conjuntos. O produto de um conjunto de dois elementos e um conjunto de seis elementos é um conjunto de 12 elementos, ou seja, 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 cada nome com cada produto, resultando em seis elementos.

Cartesian product

Em bancos de dados, um produto cartesiano é o resultado da combinação de cada linha de uma tabela com 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, esse não é o resultado desejado. Em T-SQL, um produto cartesiano ocorre quando duas tabelas de entrada são unidas sem considerar nenhuma relação entre elas. Sem informações sobre as relações, o processador de consulta do SQL Server vai retornar todas as combinações possíveis de linhas. Esse resultado pode ter algumas aplicações práticas, como a geração de dados de teste, mas normalmente não é útil e pode ter implicações de desempenho graves.

Com o advento do padrão ANSI SQL-92, foi adicionado o suporte para as cláusulas JOIN e ON de palavras-chave. O T-SQL também dá suporte a essa 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 seguinte exemplo reafirma a consulta anterior com a nova sintaxe:

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;

Observação

A sintaxe ANSI SQL-92 torna mais difícil a criação de produtos Cartesianos por acidente. Quando a palavra-chave JOIN é adicionada, um erro de sintaxe é gerado se a cláusula ON estiver ausente, a menos que a palavra-chave JOIN seja especificada como CROSS JOIN.