Junção (SQL)

Uma junção interna requer que cada linha nas duas tabelas unidas tenha valores de coluna correspondentes e é uma operação de junção comumente usada em aplicativos, mas não deve ser considerada a melhor escolha em todas as situações. A junção interna cria uma nova tabela de resultados combinando valores de coluna de duas tabelas (A e B) com base no predicado de junção. A consulta compara cada linha de A com cada linha de B para encontrar todos os pares de linhas que satisfazem o predicado de junção. Quando o predicado de junção é satisfeito combinando valores não NULL, os valores da coluna para cada par de linhas combinadas de A e B são combinados em uma linha de resultado.

O resultado da junção pode ser definido como o resultado de primeiro obter o produto cartesiano (ou junção cruzada) de todas as linhas nas tabelas (combinando cada linha na tabela A com cada linha na tabela B) e, em seguida, retornar todas as linhas que satisfaçam o predicado de junção. As implementações reais de SQL normalmente usam outras abordagens, como hash joins ou sort-merge joins, uma vez que calcular o produto cartesiano é mais lento e geralmente exige uma quantidade proibitivamente grande de memória para armazenar.

SQL especifica dois sintáticos diferentes maneiras de expressar junções: a “notação de junção explícita” e a “notação de junção implícita”. A “notação de junção implícita” não é mais considerada uma prática recomendada, embora os sistemas de banco de dados ainda a suportem.

A “notação de junção explícita” usa a palavra-chave JOIN, precedido opcionalmente pela palavra-chave INNER, para especificar a tabela a ser juntada, e a palavra-chave ON para especificar os predicados para a junção, como em o seguinte exemplo:

SELECT employee.LastName, employee.DepartmentID, department.DepartmentName FROM employee INNER JOIN department ONemployee.DepartmentID = department.DepartmentID;

Employee.LastName Employee.DepartmentID Department.DepartmentName
Robinson 34 Clerical
Jones 33 Engenharia
Smith 34 Clerical
Heisenberg 33 Engenharia
Rafferty 31 Vendas

A “notação de junção implícita” simplesmente lista t s tabelas para juntar, na cláusula FROM da instrução SELECT, usando vírgulas para separá-las. Assim, ele especifica uma junção cruzada e a cláusula WHERE pode aplicar predicados de filtro adicionais (que funcionam de forma comparável aos predicados de junção na notação explícita).

O seguinte exemplo é equivalente ao anterior, mas desta vez usando notação de junção implícita:

SELECT employee.LastName, employee.DepartmentID, department.DepartmentName FROM employee, departmentWHERE employee.DepartmentID = department.DepartmentID;

As consultas fornecidas nos exemplos acima irá unir as tabelas Employee e Department usando a coluna DepartmentID de ambas as tabelas. Onde o DepartmentID dessas tabelas corresponder (ou seja, o predicado de junção é satisfeito), a consulta combinará as colunas LastName, DepartmentID e DepartmentName das duas tabelas em uma linha de resultado. Onde o DepartmentID não corresponde, nenhuma linha de resultado é gerada.

Portanto, o resultado da execução da consulta acima será:

Employee.LastName Employee.DepartmentID Department.DepartmentName
Robinson 34 Escritório
Jones 33 Engenharia
Smith 34 Escritório
Heisenberg 33 Engenharia
Rafferty 31 Vendas

O funcionário “Williams” e o departamento “Marketing” não aparecem nos resultados da execução da consulta. Nenhum deles possui linhas correspondentes na outra tabela respectiva: “Williams” não possui departamento associado e nenhum funcionário possui o ID de departamento 35 (“Marketing”). Dependendo dos resultados desejados, esse comportamento pode ser um bug sutil, que pode ser evitado substituindo a junção interna por uma junção externa.

junção interna e edição de valores NULL

Os programadores devem usar cuidado especial ao juntar tabelas em colunas que podem conter valores NULL, uma vez que NULL nunca corresponderá a nenhum outro valor (nem mesmo o próprio NULL), a menos que a condição de junção use explicitamente um predicado de combinação que primeiro verifica se as colunas de junção são NOT NULL antes de aplicar a (s) condição (ões) de predicado restante. O Inner Join só pode ser usado com segurança em um banco de dados que imponha integridade referencial ou onde as colunas de junção não sejam NULL. Muitos bancos de dados relacionais de processamento de transações contam com padrões de atualização de dados de Atomicidade, Consistência, Isolamento e Durabilidade (ACID) para garantir a integridade dos dados, tornando as junções internas uma escolha apropriada. No entanto, os bancos de dados de transações geralmente também têm colunas de junção desejáveis que podem ser NULL.Muitos bancos de dados relacionais e data warehouses de relatórios usam atualizações em lote Extract, Transform, Load (ETL) de alto volume que tornam a integridade referencial difícil ou impossível de aplicar, resultando em colunas de junção potencialmente NULL que um autor de consulta SQL não pode modificar e que fazem com que as junções internas omitem dados sem indicação de erro. A escolha de usar uma junção interna depende do design do banco de dados e das características dos dados. Uma junção externa esquerda geralmente pode ser substituída por uma junção interna quando as colunas de junção em uma tabela podem conter valores NULL.

Qualquer coluna de dados que pode ser NULL (vazia) nunca deve ser usada como um link em um junção interna, a menos que o resultado pretendido seja eliminar as linhas com o valor NULL. Se as colunas de junção NULL devem ser deliberadamente removidas do conjunto de resultados, uma junção interna pode ser mais rápida do que uma junção externa porque a junção de tabela e a filtragem são feitas em uma única etapa. Por outro lado, uma junção interna pode resultar em um desempenho desastrosamente lento ou até mesmo em uma falha do servidor quando usada em uma consulta de grande volume em combinação com funções de banco de dados em uma cláusula SQL Where. Uma função em uma cláusula SQL Where pode fazer com que o banco de dados ignore índices de tabela relativamente compactos. O banco de dados pode ler e unir internamente as colunas selecionadas de ambas as tabelas antes de reduzir o número de linhas usando o filtro que depende de um valor calculado, resultando em uma quantidade relativamente enorme de processamento ineficiente.

Quando um conjunto de resultados é produzido pela junção de várias tabelas, incluindo tabelas mestras usadas para procurar descrições de texto completo de códigos de identificadores numéricos (uma tabela de pesquisa), um valor NULL em qualquer uma das chaves estrangeiras pode resultar na eliminação de toda a linha do conjunto de resultados, sem indicação de erro. Uma consulta SQL complexa que inclui uma ou mais junções internas e várias junções externas tem o mesmo risco de valores NULL nas colunas de link de junção interna.

Um compromisso com o código SQL contendo junções internas pressupõe que as colunas de junção NULL não ser introduzido por mudanças futuras, incluindo atualizações de fornecedor, alterações de design e processamento em massa fora das regras de validação de dados do aplicativo, como conversões de dados, migrações, importações em massa e mesclagens.

É possível classificar junções internas como equi-joins, como junções naturais ou como cross-joins.

Equi-joinEdit

Uma equi-join é um tipo específico de junção baseada em comparador, que usa apenas comparações de igualdade no predicado de junção. O uso de outros operadores de comparação (como <) desqualifica uma junção como junção de igualdade. A consulta mostrada acima já forneceu um exemplo de junção de igualdade:

SELECT *FROM employee JOIN department ON employee.DepartmentID = department.DepartmentID;

Podemos escrever equi-join como abaixo,

SELECT *FROM employee, departmentWHERE employee.DepartmentID = department.DepartmentID;

Se co lumns em um equi-join têm o mesmo nome, SQL-92 fornece uma notação abreviada opcional para expressar equi-joins, por meio da construção USING:

SELECT *FROM employee INNER JOIN department USING (DepartmentID);

A construção USING é mais do que mero açúcar sintático, no entanto, uma vez que o conjunto de resultados difere do resultado conjunto da versão com o predicado explícito. Especificamente, quaisquer colunas mencionadas na lista USING aparecerão apenas uma vez, com um nome não qualificado, em vez de uma vez para cada tabela na junção. No caso acima, haverá uma única coluna DepartmentID e nenhuma employee.DepartmentID ou department.DepartmentID .

A cláusula USING não é suportada pelo MS SQL Server e Sybase.

JoinEdit natural

O natural join é um caso especial de equi-join. A junção natural (⋈) é um operador binário que é escrito como (R ⋈ S) onde R e S são relações. O resultado da junção natural é o conjunto de todas as combinações de tuplas em R e S que são iguais em seus nomes de atributos comuns.Para um exemplo, considere as tabelas Employee e Dept e sua junção natural:

Funcionário
Nome EmpId DeptName
Harry 3415 Finanças
Sally 2241 Vendas
George 3401 Finanças
Harriet 2202 Vendas
Dept
Nome do departamento Gerente
Finanças George
Vendas Harriet
Produção Charles
Funcionário ⋈ {\ displaystyle \ bowtie} Departamento
Nome EmpId Nome do departamento Gerente
Harry 3415 Finanças George
Sally 2241 Vendas Harriet
George 3401 Finanças George
Harriet 2202 Vendas Harriet

Isso também pode ser usado para definir a composição das relações. Por exemplo, a composição de Employee e Dept é sua junção conforme mostrado acima, projetada em todos, exceto no atributo comum DeptName. Na teoria da categoria, a junção é precisamente o produto de fibra.

A junção natural é indiscutivelmente um dos operadores mais importantes, pois é a contraparte relacional do AND lógico. Observe que se a mesma variável aparecer em cada um dos dois predicados que estão conectados por AND, então essa variável representa a mesma coisa e ambas as aparências devem sempre ser substituídas pelo mesmo valor. Em particular, a junção natural permite a combinação de relações que são associadas por uma chave estrangeira. Por exemplo, no exemplo acima, uma chave estrangeira provavelmente contém de Employee.DeptName a Dept.DeptName e, em seguida, a junção natural de Employee e Dept combina todos os funcionários com seus departamentos. Isso funciona porque a chave estrangeira é mantida entre atributos com o mesmo nome. Se esse não for o caso, como na chave estrangeira de Dept.manager para Employee.Name, essas colunas devem ser renomeadas antes que a junção natural seja realizada. Essa junção às vezes também é chamada de junção de igualdade.

Mais formalmente, a semântica da junção natural é definida da seguinte forma:

R ⋈ S = {t ∪ s ∣ t ∈ R ∧ s ∈ S ∧ F un (t ∪ s)} {\ displaystyle R \ bowtie S = \ left \ {t \ cup s \ mid t \ in R \ \ land \ s \ in S \ \ land \ {\ mathit {Fun}} (t \ cup s) \ right \}},

onde Fun é um predicado que é verdadeiro para uma relação r se e somente se r for uma função. Normalmente é necessário que R e S tenham pelo menos um atributo comum, mas se essa restrição for omitida e R e S não tiverem atributos comuns, a junção natural torna-se exatamente o produto cartesiano.

O junção natural pode ser simulada com primitivas de Codd da seguinte maneira. Sejam c1,…, cm os nomes de atributos comuns a R e S, r1, …, rn os nomes de atributos exclusivos de R e sejam s1, …, sk seja o atributos únicos para S. Além disso, assuma que os nomes dos atributos x1,…, xm não estão em R nem em S. Em uma primeira etapa, os nomes de atributos comuns em S podem agora ser renomeados:

T = ρ x 1 / c 1,…, xm / cm (S) = ρ x 1 / c 1 (ρ x 2 / c 2 (… ρ xm / cm (S)…)) {\ displaystyle T = \ rho _ {x_ {1} / c_ {1}, \ ldots, x_ {m} / c_ {m}} (S) = \ rho _ {x_ {1} / c_ {1}} (\ rho _ {x_ {2} / c_ {2 }} (\ ldots \ rho _ {x_ {m} / c_ {m}} (S) \ ldots))}

Então pegamos o produto cartesiano e selecionamos as tuplas que devem ser unidas:

U = π r 1,…, rn, c 1,…, cm, s 1,…, sk (P) {\ displaystyle U = \ pi _ {r_ {1}, \ ldots, r_ {n}, c_ {1}, \ ldots, c_ {m}, s_ {1}, \ ldots, s_ {k}} (P)}

Uma junção natural é um tipo de equi- join onde o predicado de junção surge implicitamente, comparando todas as colunas em ambas as tabelas que têm os mesmos nomes de coluna nas tabelas unidas. A tabela combinada resultante contém apenas uma coluna para cada par de colunas com nomes iguais. No caso de nenhuma coluna com os mesmos nomes ser encontrada, o resultado é uma junção cruzada.

A maioria dos especialistas concorda que os NATURAL JOINs são perigosos e, portanto, desencorajam fortemente seu uso. O perigo vem de adicionar inadvertidamente uma nova coluna, com o mesmo nome de outra coluna na outra tabela. Uma junção natural existente pode então “naturalmente” usar a nova coluna para comparações, fazendo comparações / correspondências usando critérios diferentes (de colunas diferentes) do que antes. Assim, uma consulta existente pode produzir resultados diferentes, mesmo que os dados nas tabelas não tenham sido alterados, mas apenas aumentados.O uso de nomes de coluna para determinar automaticamente os links de tabelas não é uma opção em grandes bancos de dados com centenas ou milhares de tabelas, onde colocaria uma restrição irreal nas convenções de nomenclatura. Os bancos de dados do mundo real são comumente projetados com dados de chave estrangeira que não são preenchidos de forma consistente (valores NULL são permitidos), devido às regras de negócios e ao contexto. É uma prática comum modificar nomes de colunas de dados semelhantes em tabelas diferentes e essa falta de consistência rígida relega as junções naturais a um conceito teórico para discussão.

A consulta de exemplo acima para junções internas pode ser expressa como um natural junte-se da seguinte maneira:

SELECT *FROM employee NATURAL JOIN department;

Tal como acontece com a cláusula USING explícita, apenas uma coluna DepartmentID ocorre na tabela associada, sem qualificador:

DepartmentID Employee.LastName Department.DepartmentName
34 Smith Clerical
33 Jones Engenharia
34 Robinson Clerical
33 Heisenberg Engenharia
31 Rafferty Vendas

PostgreSQL, MySQL e Oracle su pport junções naturais; Microsoft T-SQL e IBM DB2 não. As colunas usadas na junção são implícitas, portanto, o código de junção não mostra quais colunas são esperadas e uma mudança nos nomes das colunas pode alterar os resultados. No padrão SQL: 2011, as junções naturais fazem parte do pacote opcional F401, “Tabela combinada estendida”.

Em muitos ambientes de banco de dados, os nomes das colunas são controlados por um fornecedor externo, não pelo desenvolvedor de consultas. Uma junção natural pressupõe estabilidade e consistência nos nomes das colunas, que podem mudar durante as atualizações de versão obrigatórias do fornecedor.

Write a Comment

O seu endereço de email não será publicado. Campos obrigatórios marcados com *