Junção SQL e diferentes tipos de juntas

o que é um SQL {[[0]} e quais são os diferentes tipos?

Author: TylerH, 2013-07-30

7 answers

Uma ilustração de W3schools:


INNER JOIN - Only records which match the condition in both tables


LEFT JOIN - All records from table 1 in conjunction with records which match the condition in table 2


RIGHT JOIN - All records from table 2 in conjunction with records from table 1 which match the condition


FULL OUTER JOIN - Combination of both Left and Right Outer joins matching ON clause but preserving both tables


 315
Author: Anup, 2018-03-07 19:23:43
O que é isso?

SQL JOIN é um método para recuperar dados de duas ou mais tabelas de banco de dados.

Quais são as diferentes ?

Há um total de cinco JOIN s. Eles são:

  1. JOIN or INNER JOIN
  2. OUTER JOIN

     2.1 LEFT OUTER JOIN or LEFT JOIN
     2.2 RIGHT OUTER JOIN or RIGHT JOIN
     2.3 FULL OUTER JOIN or FULL JOIN

  3. NATURAL JOIN
  4. CROSS JOIN
  5. SELF JOIN

1. Junção ou junção interior:

Neste tipo de a JOIN, temos todos os registos que correspondem à condição em ambas as tabelas, e os registos em ambas as tabelas que não correspondem não são reportados.

Por outras palavras, INNER JOIN baseia-se no facto único de: as entradas correspondentes em ambas as tabelas devem ser listadas.

Note que um JOIN sem qualquer outro JOIN palavras-chave (como INNER, OUTER, LEFT, etc) é um INNER JOIN. Por outras palavras, JOIN é a syntactic sugar for INNER JOIN (see: Difference between JOIN and INNER JOIN).

2. JUNÇÃO EXTERIOR:

OUTER JOIN recupera

Quer, as linhas correspondentes de uma tabela e todas as linhas da outra tabela Ou, todas as linhas em todas as tabelas (não importa se ou não há um jogo).

Existem três tipos de juntas exteriores:

2.1 junção exterior esquerda ou junção esquerda

Este conjunto devolve todas as linhas da tabela esquerda em conjunto com as linhas correspondentes da mesa direita. Se não existirem colunas correspondentes na tabela à direita, devolve os valores NULL.

2.2 junção exterior direita ou junção direita

Este JOIN devolve todas as linhas da tabela direita em conjunto com a correspondência linhas a partir da mesa esquerda. Se não existirem colunas correspondentes na tabela esquerda, devolve os valores NULL.

2.3 junção exterior completa ou junção completa

Este JOIN combina LEFT OUTER JOIN e RIGHT OUTER JOIN. Devolve as linhas de qualquer das tabelas quando as condições são cumpridas e devolve o valor NULL quando não há correspondência.

Por outras palavras, OUTER JOIN baseia-se no facto de: apenas as entradas correspondentes numa das tabelas (direita ou esquerda) ou ambas as tabelas(completas) devem ser constar.

Note that `OUTER JOIN` is a loosened form of `INNER JOIN`.

3. JUNÇÃO NATURAL:

Baseia-se nas duas condições :

  1. o JOIN é feito em todas as colunas com o mesmo nome para a igualdade.
  2. remove colunas duplicadas do resultado.
Isto parece ser mais de natureza teórica e como resultado (provavelmente) da maioria dos DBMS nem te dês ao trabalho de apoiar isto.

4. JUNÇÃO CRUZADA:

É o produto cartesiano das duas tabelas envolvidas. O resultado de uma CROSS JOIN não fará sentido. na maioria das situações. Além disso, não vamos precisar disso de todo (ou precisa menos, para ser preciso).

5. AUTO-ADESÃO:

Não é uma forma diferente de JOIN, mas é um JOIN (INNER, OUTER, etc) de uma mesa para si.

Juntas baseadas em operadores

Dependendo do operador utilizado para uma cláusula JOIN, podem existir dois tipos de JOIN S. são

  1. Junta de Equi
  2. {\POS (192,220)} a teta junta-se {\POS (192,220)}

1. Junção Equi:

Para qualquer tipo JOIN(INNER, OUTER, etc), se usarmos apenas o operador de igualdade ( = ), então dizemos que o JOIN é um EQUI JOIN.

2. Adesão Theta:

Isto é o mesmo que EQUI JOIN mas permite que todos os outros operadores como >, = etc.

Muitos consideram tanto EQUI JOIN Como Theta JOIN semelhantes a INNER, OUTER mas acredito firmemente que é um erro e que comete ideias Vagas. Porque ... INNER JOIN, OUTER JOIN etc estão todos ligados com os quadros e os seus dados, considerando que EQUI JOIN e THETA JOIN são apenas conectados com os operadores que usamos no primeiro.

Mais uma vez, há muitos que consideram NATURAL JOIN como uma espécie de "peculiar" EQUI JOIN. Na verdade, é verdade, por causa da primeira condição que mencionei para NATURAL JOIN. No entanto, não temos de o fazer. restrinja isso apenas a NATURAL JOIN S. INNER JOIN s, OUTER JOIN s etc poderia ser um EQUI JOIN demasiado.
 218
Author: M-D, 2018-06-09 22:45:46

Definição:


JOINS são uma forma de consultar os dados que se combinaram a partir de várias tabelas simultaneamente.

Tipos de juntas:


Preocupação com os RDBMS existem 5 tipos de junções:

  • Equi-Join: combina registos comuns de dois quadros baseados na condição de igualdade. Tecnicamente, a junção feita utilizando o equality-operator (=) para comparar os valores da chave primária de uma tabela e os valores-chave de foriegn de antoher table, hence result set includes common (matched) records from both tables. Para a implementação veja INNER-JOIN.

  • Natural-Join: é uma versão melhorada de Equi-Join, em que seleccionar a operação omite a coluna duplicada. Para a implementação, ver INNER-JOIN

  • Non-Equi-Join: it is reverse of Equi-join where join condition is uses other than equal operator(=) e. g., !=, =, >,

  • Self-Join: : um comportamento personalizado de join onde uma tabela combinada com ela mesma; isto é tipicamente necessário para pesquisar tabelas de auto-referenciação (ou entidade de relacionamento unário). Para a implementação, ver Ligações internas.

  • Produto cartesiano: {[13] } combina todos os registos de ambas as tabelas sem qualquer condição. Tecnicamente, ele retorna o conjunto de resultados de uma consulta sem a cláusula onde -.

De acordo com a SQL concern e advancement, there are 3-types of joins and all RDBMS joins can be achvied using these types of joins.

  1. Junção interna: junta-se (ou combinações) linhas correspondentes de duas tabelas. A correspondência é feita com base em colunas comuns de tabelas e sua operação de comparação. Se a condição baseada na equailidade for então: equi-JOIN realizada, caso contrário não EQUI-Join.

  2. * * junção exterior: * * funde (ou combina) linhas correspondentes de duas tabelas e linhas não compensadas com NULL valores. No entanto, pode personalizar a selecção das linhas não correspondidas, por exemplo, seleccionando a linha não compensada da primeira tabela ou segunda tabela por sub-tipos: junção externa esquerda e junção externa direita.

    2.1. junção exterior esquerda (t. c. p., junção à esquerda): devolve as linhas correspondentes formam duas tabelas e não são acopladas apenas da mesa esquerda(I. E., primeira tabela).

    2.2. junção exterior à direita (t. c. p., junção à direita): devolve as linhas correspondentes de duas tabelas e não comparadas apenas da tabela à direita.

    2.3. junção exterior completa (junta externa.K. A.): Devolve igual e não igualada em ambas as tabelas.

  3. Junção cruzada: esta junção não se funde/combinações em vez disso, executa o produto cartisiano.

enter image description hereNota: A Auto-junção pode ser achivada por qualquer uma das juntas internas, externas e cruzadas com base na exigência, mas a mesa deve unir-se a si mesma.

Para mais informações:

Exemplos:

1.1: junção interior: junção Equi execução

SELECT  *
FROM Table1 A 
 INNER JOIN Table2 B ON A.<PrimaryKey> =B.<ForeignKey>;

1.2: INNER-JOIN: Natural-JOIN implementation

Select A.*, B.Col1, B.Col2          --But no B.ForiengKyeColumn in Select
 FROM Table1 A
 INNER JOIN Table2 B On A.Pk = B.Fk;

1.3: INNER-JOIN with NON-Eqijoin implementation

Select *
 FROM Table1 A INNER JOIN Table2 B On A.Pk <= B.Fk;

1.4: INNER-JOIN with SELF-JOIN

Select *
 FROM Table1 A1 INNER JOIN Table1 A2 On A1.Pk = A2.Fk;

2.1: junção exterior (junção exterior completa))

Select *
 FROM Table1 A FULL OUTER JOIN Table2 B On A.Pk = B.Fk;

2.2: JUNÇÃO À ESQUERDA

Select *
 FROM Table1 A LEFT OUTER JOIN Table2 B On A.Pk = B.Fk;

2.3: JUNÇÃO À DIREITA

Select *
 FROM Table1 A RIGHT OUTER JOIN Table2 B On A.Pk = B.Fk;

3.1: JUNÇÃO CRUZADA

Select *
 FROM TableA CROSS JOIN TableB;

3.2: junção cruzada-Auto Juntar

Select *
 FROM Table1 A1 CROSS JOIN Table1 A2;

/ / ou / /

Select *
 FROM Table1 A1,Table1 A2;
 61
Author: nayeemDotNetAuthorities, 2016-07-01 06:11:31
Curiosamente, a maioria das outras respostas sofre destes dois problemas:

Escrevi recentemente um artigo sobre o tema: um guia provavelmente incompleto e abrangente para as muitas maneiras diferentes de juntar tabelas em SQL , que vou resumir aqui.

Primeiro e mais importante: As juntas são produtos cartesianos

É por isso que os diagramas de Venn os explicam de forma tão imprecisa, porque uma junção cria um produto cartesiano entre as duas tabelas unidas. A Wikipédia ilustra-o bem:

enter image description here

A sintaxe SQL para produtos Cartesianos é CROSS JOIN. Por exemplo:

SELECT *

-- This just generates all the days in January 2017
FROM generate_series(
  '2017-01-01'::TIMESTAMP,
  '2017-01-01'::TIMESTAMP + INTERVAL '1 month -1 day',
  INTERVAL '1 day'
) AS days(day)

-- Here, we're combining all days with all departments
CROSS JOIN departments

Que combina todas as linhas de uma tabela com todas as linhas da outra quadro:

Fonte:

+--------+   +------------+
| day    |   | department |
+--------+   +------------+
| Jan 01 |   | Dept 1     |
| Jan 02 |   | Dept 2     |
| ...    |   | Dept 3     |
| Jan 30 |   +------------+
| Jan 31 |
+--------+
Resultado:
+--------+------------+
| day    | department |
+--------+------------+
| Jan 01 | Dept 1     |
| Jan 01 | Dept 2     |
| Jan 01 | Dept 3     |
| Jan 02 | Dept 1     |
| Jan 02 | Dept 2     |
| Jan 02 | Dept 3     |
| ...    | ...        |
| Jan 31 | Dept 1     |
| Jan 31 | Dept 2     |
| Jan 31 | Dept 3     |
+--------+------------+
Se escrevermos uma lista separada por vírgulas de tabelas, teremos o mesmo:
-- CROSS JOINing two tables:
SELECT * FROM table1, table2

Junta interna (junta Teta)

An INNER JOIN é apenas um filtrado CROSS JOIN onde o predicado do filtro é chamado Theta em álgebra relacional.

Por exemplo:

SELECT *

-- Same as before
FROM generate_series(
  '2017-01-01'::TIMESTAMP,
  '2017-01-01'::TIMESTAMP + INTERVAL '1 month -1 day',
  INTERVAL '1 day'
) AS days(day)

-- Now, exclude all days/departments combinations for
-- days before the department was created
JOIN departments AS d ON day >= d.created_at

Note que a palavra-chave INNER é opcional (excepto no MS Access).

(veja o artigo para o resultado exemplos)

JUNTA DE EQUI

Um tipo especial de Teta-JOIN é equi JOIN, que usamos mais. O predicado junta a chave primária de uma tabela com a chave estrangeira de outra tabela. Se usarmos a base de dados Sakila para ilustração, podemos escrever:
SELECT *
FROM actor AS a
JOIN film_actor AS fa ON a.actor_id = fa.actor_id
JOIN film AS f ON f.film_id = fa.film_id
Isto combina todos os actores com os seus filmes.

Ou também, em algumas bases de dados:

SELECT *
FROM actor
JOIN film_actor USING (actor_id)
JOIN film USING (film_id)

A sintaxe USING() permite especificar uma coluna que deve estar presente em ambos os lados de uma junção as tabelas da operação e cria um predicado de igualdade nessas duas colunas.

JUNÇÃO NATURAL

Outras respostas listaram este" tipo de junção " separadamente, mas isso não faz sentido. É apenas uma forma de açúcar sintaxe para a junção equi, que é um caso especial de teta-junção ou junção interna. A junção NATURAL recolhe simplesmente todas as colunas que são comuns a ambas as tabelas que estão a ser unidas e juntas USING() aquelas colunas. O que quase nunca é útil, por causa de fósforos acidentais (como LAST_UPDATE colunas na base de dados Sakila ).

Aqui está a sintaxe:
SELECT *
FROM actor
NATURAL JOIN film_actor
NATURAL JOIN film

JUNTA EXTERIOR

Agora, {[26] } é um pouco diferente de {[19] } porque cria um UNION de vários produtos cartesianos. Podemos escrever:

-- Convenient syntax:
SELECT *
FROM a LEFT JOIN b ON <predicate>

-- Cumbersome, equivalent syntax:
SELECT a.*, b.*
FROM a JOIN b ON <predicate>
UNION ALL
SELECT a.*, NULL, NULL, ..., NULL
FROM a
WHERE NOT EXISTS (
  SELECT * FROM b WHERE <predicate>
)

Ninguém quer escrever o último, então nós escrevemos OUTER JOIN (que é geralmente melhor otimizado por bases de dados).

Como INNER, a palavra-chave OUTER é opcional, aqui.

OUTER JOIN tem três sabores:

  • LEFT [ OUTER ] JOIN: a tabela à esquerda da expressão JOIN é adicionada à União como indicado acima.
  • RIGHT [ OUTER ] JOIN: a tabela direita da expressão JOIN é acrescentada à União, tal como se mostra acima.
  • FULL [ OUTER ] JOIN: Os dois quadros da expressão JOIN são acrescentados à União, como indicado acima.

Todos estes podem ser combinados com a palavra-chave USING() ou com NATURAL (eu realmente tive um verdadeiro mundo de caso de uso para um NATURAL FULL JOIN recentemente)

Sintaxes alternativas

Há alguns sintaxas históricas e desactualizadas no servidor Oracle e SQL, que suportavam OUTER JOIN já antes do padrão SQL tinha uma sintaxe para isso:
-- Oracle
SELECT *
FROM actor a, film_actor fa, film f
WHERE a.actor_id = fa.actor_id(+)
AND fa.film_id = f.film_id(+)

-- SQL Server
SELECT *
FROM actor a, film_actor fa, film f
WHERE a.actor_id *= fa.actor_id
AND fa.film_id *= f.film_id
Dito isto, não use esta sintaxe. Eu apenas listar isso aqui para que você possa reconhecê-lo a partir de posts antigos / código legado.

Particionado OUTER JOIN

Poucas pessoas sabem disso, mas o padrão SQL especifica particionado {[[26]} (e Oracle implementa isso). Você pode escrever coisas assim:

WITH

  -- Using CONNECT BY to generate all dates in January
  days(day) AS (
    SELECT DATE '2017-01-01' + LEVEL - 1
    FROM dual
    CONNECT BY LEVEL <= 31
  ),

  -- Our departments
  departments(department, created_at) AS (
    SELECT 'Dept 1', DATE '2017-01-10' FROM dual UNION ALL
    SELECT 'Dept 2', DATE '2017-01-11' FROM dual UNION ALL
    SELECT 'Dept 3', DATE '2017-01-12' FROM dual UNION ALL
    SELECT 'Dept 4', DATE '2017-04-01' FROM dual UNION ALL
    SELECT 'Dept 5', DATE '2017-04-02' FROM dual
  )
SELECT *
FROM days 
LEFT JOIN departments 
  PARTITION BY (department) -- This is where the magic happens
  ON day >= created_at

Partes da embalagem resultado:

+--------+------------+------------+
| day    | department | created_at |
+--------+------------+------------+
| Jan 01 | Dept 1     |            | -- Didn't match, but still get row
| Jan 02 | Dept 1     |            | -- Didn't match, but still get row
| ...    | Dept 1     |            | -- Didn't match, but still get row
| Jan 09 | Dept 1     |            | -- Didn't match, but still get row
| Jan 10 | Dept 1     | Jan 10     | -- Matches, so get join result
| Jan 11 | Dept 1     | Jan 10     | -- Matches, so get join result
| Jan 12 | Dept 1     | Jan 10     | -- Matches, so get join result
| ...    | Dept 1     | Jan 10     | -- Matches, so get join result
| Jan 31 | Dept 1     | Jan 10     | -- Matches, so get join result

O ponto aqui é que todas as linhas do lado particionado da junção vão acabar no resultado, independentemente se o JOIN corresponder qualquer coisa no "outro lado da junção". Resumindo: isto é para preencher dados esparsos em relatórios. Muito útil!

SEMI-JUNTA

A sério? Nenhuma outra resposta percebeu isto? Claro que não, porque não tem uma sintaxe nativa em SQL, infelizmente (tal como o anti JOIN abaixo). Mas podemos usar IN() e EXISTS(), por exemplo, para encontrar todos os actores que actuaram em filmes:
SELECT *
FROM actor a
WHERE EXISTS (
  SELECT * FROM film_actor fa
  WHERE a.actor_id = fa.actor_id
)

O predicado WHERE a.actor_id = fa.actor_id actua como o predicado de semi-junção. Se você não acredita, confira os planos de execução, por exemplo, em Oracle. Você verá que a base de dados executa uma operação de semi-adesão, não o predicado EXISTS().

enter image description here

ANTI JUNTAR

Isto é exatamente o oposto de semi-junção (tenha cuidado para não usar NOT IN embora , pois tem uma importante advertência) {[[62]} Aqui. todos os actores sem Filmes:

SELECT *
FROM actor a
WHERE NOT EXISTS (
  SELECT * FROM film_actor fa
  WHERE a.actor_id = fa.actor_id
)
Algumas pessoas (especialmente as pessoas de MySQL) também escrevem anti JOIN assim:
SELECT *
FROM actor a
LEFT JOIN film_actor fa
USING (actor_id)
WHERE film_id IS NULL
Acho que a razão histórica é o desempenho.

JUNÇÃO LATERAL

Meu Deus, este é demasiado fixe. Sou o único a mencioná-lo? Aqui está uma consulta legal:
SELECT a.first_name, a.last_name, f.*
FROM actor AS a
LEFT OUTER JOIN LATERAL (
  SELECT f.title, SUM(amount) AS revenue
  FROM film AS f
  JOIN film_actor AS fa USING (film_id)
  JOIN inventory AS i USING (film_id)
  JOIN rental AS r USING (inventory_id)
  JOIN payment AS p USING (rental_id)
  WHERE fa.actor_id = a.actor_id -- JOIN predicate with the outer query!
  GROUP BY f.film_id
  ORDER BY revenue DESC
  LIMIT 5
) AS f
ON true
Vai encontrar as 5 melhores receitas de filmes por actor. Sempre que precisar de uma consulta TOP-N-per-something, LATERAL JOIN será seu amigo. Se você é uma pessoa do servidor SQL, então você sabe que este JOIN tipo sob o nome APPLY
SELECT a.first_name, a.last_name, f.*
FROM actor AS a
OUTER APPLY (
  SELECT f.title, SUM(amount) AS revenue
  FROM film AS f
  JOIN film_actor AS fa ON f.film_id = fa.film_id
  JOIN inventory AS i ON f.film_id = i.film_id
  JOIN rental AS r ON i.inventory_id = r.inventory_id
  JOIN payment AS p ON r.rental_id = p.rental_id
  WHERE fa.actor_id = a.actor_id -- JOIN predicate with the outer query!
  GROUP BY f.film_id
  ORDER BY revenue DESC
  LIMIT 5
) AS f

Ok, talvez isso seja batota, porque uma expressão LATERAL JOIN ou APPLY é realmente uma" subconjunta correlacionada " que produz várias linhas. Mas se permitirmos "subcontingentes correlacionados", também podemos falar sobre isso...

MULTISET

Isto só é realmente implementado pela Oracle e Informix( tanto quanto sei), mas pode ser emulado em PostgreSQL usando arrays e/ou XML e no servidor SQL usando XML.

MULTISET produz um subquery correlacionado e ninhos o conjunto resultante de linhas na consulta externa. A consulta abaixo seleciona todos os atores e para cada ator recolhe seus filmes em uma coleção aninhada:

SELECT a.*, MULTISET (
  SELECT f.*
  FROM film AS f
  JOIN film_actor AS fa USING (film_id)
  WHERE a.actor_id = fa.actor_id
) AS films
FROM actor
Como já viste, há mais tipos de juntas do que apenas o "chato"" INNER, OUTER, e CROSS JOIN que são normalmente mencionados. mais detalhes no meu artigo. E por favor, pare de usar diagramas Venn para ilustrá-los.
 33
Author: Lukas Eder, 2017-04-21 17:08:07

No servidor SQL, existem diferentes tipos de junções.

  1. JUNÇÃO CRUZADA
  2. JUNTA INTERNA
  3. JUNÇÃO EXTERIOR

As juntas exteriores são novamente divididas em 3 tipos

    ([10]}junção esquerda ou junção exterior esquerda ([10]}Junção À Direita ou junção exterior à direita
  1. junção completa ou junção total exterior

enter image description here

enter image description here

Junta ou interior Juntar

SELECT Name, Gender, Salary, DepartmentName
FROM tblEmployee
INNER JOIN tblDepartment
ON tblEmployee.DepartmentId = tblDepartment.Id

OR

SELECT Name, Gender, Salary, DepartmentName
FROM tblEmployee
JOIN tblDepartment
ON tblEmployee.DepartmentId = tblDepartment.Id

enter image description here

Junção esquerda ou junção exterior esquerda

SELECT Name, Gender, Salary, DepartmentName
FROM tblEmployee
LEFT OUTER JOIN tblDepartment
ON tblEmployee.DepartmentId = tblDepartment.Id

OR

SELECT Name, Gender, Salary, DepartmentName
FROM tblEmployee
LEFT JOIN tblDepartment
ON tblEmployee.DepartmentId = tblDepartment.Id

enter image description here

Junção à direita ou junção exterior à direita

SELECT Name, Gender, Salary, DepartmentName
FROM tblEmployee
RIGHT OUTER JOIN tblDepartment
ON tblEmployee.DepartmentId = tblDepartment.Id

OR

SELECT Name, Gender, Salary, DepartmentName
FROM tblEmployee
RIGHT JOIN tblDepartment
ON tblEmployee.DepartmentId = tblDepartment.Id

enter image description here

Junção completa ou junção exterior completa

SELECT Name, Gender, Salary, DepartmentName
FROM tblEmployee
FULL OUTER JOIN tblDepartment
ON tblEmployee.DepartmentId = tblDepartment.Id

OR

SELECT Name, Gender, Salary, DepartmentName
FROM tblEmployee
FULL JOIN tblDepartment
ON tblEmployee.DepartmentId = tblDepartment.Id

enter image description here

enter image description here

enter image description here

 21
Author: Rae Lee, 2015-10-28 19:13:45
Criei uma ilustração que explica melhor do que as palavras, na minha opinião.: SQL Join table of explanation
 8
Author: Gisway, 2018-03-07 19:27:30

Vou pressionar o meu animal de estimação: a palavra-chave que usa.

Se ambas as tabelas de ambos os lados da junção tiverem as suas chaves estrangeiras devidamente nomeadas (ou seja, o mesmo nome, não apenas "id") então isto pode ser usado:

SELECT ...
FROM customers JOIN orders USING (customer_id)
Acho isto muito prático, legível e pouco utilizado.
 -3
Author: peufeu, 2018-03-07 19:27:51