As junções esquerda e direita do @avi são semelhantes, se você não se importa, qual é a tabela principal na qual a junção se baseia.
Anup
2
@ philipxy: Essa é uma definição estranha (mesmo se você estiver correto). Mas eu prefiro ir ao contrário e começar com junção cruzada e depois "construir" junção interna sobre ela. Afinal, o simples conceito de junção cruzada invalida esses informais e imprecisos diagrama de Venn visualisations ...
Lukas Eder
1
Essas imagens parecem sugerir que a união é a mesma que a junção externa completa e a interseção é a mesma que a junção interna, o que não é correto até onde eu sei.
mightyWOZ
1
@ DevDave, porque ao contrário da crença popular - uma imagem não vale mais que mil palavras. Veja a próxima resposta.
hyankov
248
O que é SQL JOIN?
SQL JOIN é um método para recuperar dados de duas ou mais tabelas de banco de dados.
Nesse tipo de a JOIN, obtemos todos os registros que correspondem à condição nas duas tabelas e os registros nas duas tabelas que não correspondem não são relatados.
Em outras palavras, INNER JOINé baseado no fato único de que: SOMENTE as entradas correspondentes em AMBAS as tabelas DEVEM ser listadas.
Note-se que um JOINsem quaisquer outras JOINpalavras-chave (como INNER, OUTER, LEFT, etc) é um INNER JOIN. Em outras palavras, JOINé um açúcar sintático para INNER JOIN(consulte: Diferença entre JOIN e INNER JOIN ).
2. JUNÇÃO EXTERNA:
OUTER JOIN recupera
As linhas correspondentes de uma tabela e todas as linhas da outra tabela. Ou todas as linhas de todas as tabelas (não importa se existe ou não uma correspondência).
Existem três tipos de junção externa:
2.1 JOGO EXTERIOR ESQUERDO ou JOIN ESQUERDO
Essa junção retorna todas as linhas da tabela esquerda em conjunto com as linhas correspondentes da tabela direita. Se não houver colunas correspondentes na tabela à direita, ele retornará NULLvalores.
2.2 JUNÇÃO EXTERNA DIREITA ou JUNTA DIREITA
Isso JOINretorna todas as linhas da tabela direita em conjunto com as linhas correspondentes da tabela esquerda. Se não houver colunas correspondentes na tabela esquerda, ele retornará NULLvalores.
2.3 JUNÇÃO EXTERNA COMPLETA ou JUNÇÃO COMPLETA
Isso JOINcombina LEFT OUTER JOINe RIGHT OUTER JOIN. Retorna linhas de qualquer tabela quando as condições são atendidas e retorna NULLvalor quando não há correspondência.
Em outras palavras, OUTER JOINé baseado no fato de que: SOMENTE as entradas correspondentes em UMA DAS tabelas (DIREITA ou ESQUERDA) ou AMBAS as tabelas (CHEIA) DEVEM ser listadas.
Note that `OUTERJOIN`is a loosened form of`INNERJOIN`.
3. JUNÇÃO NATURAL:
É baseado nas duas condições:
o JOINé feito em todas as colunas com o mesmo nome para igualdade.
Remove colunas duplicadas do resultado.
Isso parece ser mais de natureza teórica e, como resultado (provavelmente), a maioria dos DBMS nem se dá ao trabalho de apoiar isso.
4. JUNÇÃO TRANSVERSAL:
É o produto cartesiano das duas tabelas envolvidas. O resultado de a CROSS JOINnão fará sentido na maioria das situações. Além disso, não precisaremos disso (ou precisa, no mínimo, para ser mais preciso).
5. AUTO-JUNÇÃO:
Não é uma forma diferente de JOIN, pelo contrário, é um JOIN( INNER, OUTER, etc.) de uma mesa para si.
JOINs com base em operadores
Dependendo do operador usado para uma JOINcláusula, pode haver dois tipos de JOINs. Eles são
Equi JOIN
Theta JOIN
1. Equi JOIN:
Para qualquer JOINtipo ( INNER, OUTERetc), se usarmos SOMENTE o operador de igualdade (=), então dizemos que JOINé um EQUI JOIN.
2. Theta JOIN:
É o mesmo, EQUI JOINmas permite todos os outros operadores como>, <,> = etc.
Muitos consideram ambos EQUI JOINe Theta JOINsemelhante ao INNER, OUTER
etc JOINs. Mas acredito firmemente que é um erro e torna as idéias vagas. Porque INNER JOIN, OUTER JOINetc estão todos conectados com as tabelas e seus dados enquanto EQUI JOINe THETA JOINsó são conectados com os operadores que usamos no primeiro.
Novamente, há muitos que consideram NATURAL JOINalgum tipo de "peculiar" EQUI JOIN. De fato, é verdade, por causa da primeira condição que mencionei NATURAL JOIN. No entanto, não precisamos restringir isso simplesmente a NATURAL JOINs sozinho. INNER JOINs, OUTER JOINs etc também pode ser um EQUI JOIN.
Há relativamente novo LATERAL JOIN .. SELECT * FROM r1, LATERAL fx (r1)
Pavel Stehule
13
Embora isso pareça razoável, não acho que responda "o que é uma junção SQL" de forma alguma que transmita informações úteis. A resposta como um todo é uma referência escrita para pessoas que já entendem junções, não para o tipo de pessoa que está fazendo essas perguntas. Ele também omite referências, tanto para apoiar suas reivindicações (conforme apropriado se estiver fazendo uma resposta autorizada) quanto para fornecer explicações adicionais por meio de recursos externos. Se você estiver tentando escrever uma resposta autorizada para vincular novos usuários do SQL, pode valer a pena preencher os espaços em branco um pouco, especialmente a parte "o que é uma junção".
Craig Ringer
você pode fornecer alguns exemplos?
avi
67
Definição:
JOINS são uma maneira de consultar os dados combinados de várias tabelas simultaneamente.
Tipos de JOINS:
No que diz respeito ao RDBMS, existem 5 tipos de junções:
Equi-Join: combina registros comuns de duas tabelas com base na condição de igualdade. Tecnicamente, a Junta é feita usando o operador de igualdade (=) para comparar os valores da Chave Primária de uma tabela e da Chave Externa de outra tabela; portanto, o conjunto de resultados inclui registros comuns (correspondentes) das duas tabelas. Para implementação, consulte INNER-JOIN.
Junção natural: é uma versão aprimorada do Equi-Join, na qual a operação SELECT omite a coluna duplicada. Para implementação, consulte INNER-JOIN
Non-Equi-Join: É o inverso da Equi-join onde a condição de junção é diferente de operador igual (=), por exemplo,! =, <=,> =,>, <Ou ENTRE etc. Para implementação, consulte INNER-JOIN.
Auto- ingresso:: um comportamento personalizado de ingresso em que uma tabela se combina consigo mesma; Isso geralmente é necessário para consultar tabelas de auto-referência (ou entidade de relacionamento Unário). Para implementação, consulte INNER-JOINs.
Produto cartesiano: Cruz combina todos os registros de ambas as tabelas sem nenhuma condição. Tecnicamente, ele retorna o conjunto de resultados de uma consulta sem a cláusula WHERE.
De acordo com a preocupação e o avanço do SQL, existem três tipos de junções e todas as junções RDBMS podem ser obtidas usando esses tipos de junções.
INNER-JOIN: Mescla (ou combina) 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 igualdade, então: EQUI-JOIN for executada, caso contrário, não-EQUI-Join.
OUTER-JOIN: mescla (ou combina) linhas correspondentes de duas tabelas e linhas não correspondentes com valores NULL. No entanto, é possível customizar a seleção de linhas sem correspondência, por exemplo, selecionando a linha sem correspondência da primeira tabela ou da segunda tabela por sub-tipos: JUNÇÃO EXTERNA ESQUERDA e JUNÇÃO EXTERNA DIREITA.
2.1 LEFT Outer JOIN (também conhecido como LEFT-JOIN): Retorna linhas correspondentes de duas tabelas e não correspondentes da tabela LEFT (ou seja, primeira tabela).
2.2 JOIN externo à direita (também conhecido como JOINT à DIREITA): retorna linhas correspondentes de duas tabelas e não correspondentes apenas da tabela RIGHT.
2.3 JOGO EXTERNO COMPLETO (também conhecido como JOIN EXTERIOR): Retorna correspondidos e não correspondidos das duas tabelas.
CROSS-JOIN: Essa junção não mescla / combina, em vez disso, executa o produto cartesiano.
Nota: A auto-junção pode ser alcançada por INNER-JOIN, OUTER-JOIN e CROSS-JOIN com base no requisito, mas a tabela deve se unir.
Os rótulos "Tabela 1" e "Tabela 2" e os rótulos abaixo são inapropriados, são de ilustrações de intersect/ except/ union; aqui os círculos são as linhas retornadas por left& rightjoin, como dizem os rótulos numerados. A imagem do AXB não faz sentido. cross join= inner join on 1=1& é um caso especial do primeiro diagrama.
philipxy
Vale ressaltar que o SQL-92 define o UNION JOIN. Agora tornado obsoleto no SQL: 2003.
The Impaler
40
Curiosamente, a maioria das outras respostas sofre com esses dois problemas:
Eles se concentram apenas nas formas básicas de associação
Em primeiro lugar: JUNTAS são produtos cartesianos
É por isso que os diagramas de Venn os explicam de maneira tão imprecisa, porque um JOIN cria um produto cartesiano entre as duas tabelas unidas. A Wikipedia ilustra bem:
A sintaxe SQL para produtos cartesianos é CROSS JOIN. Por exemplo:
SELECT*-- This just generates all the days in January 2017FROM 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 departmentsCROSSJOIN departments
Que combina todas as linhas de uma tabela com todas as linhas da outra tabela:
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 apenas escrevermos uma lista de tabelas separadas por vírgula, obteremos o mesmo:
-- CROSS JOINing two tables:SELECT*FROM table1, table2
INNER JOIN (Theta-JOIN)
An INNER JOINé apenas um filtro CROSS JOINonde o predicado de filtro é chamado Thetana álgebra relacional.
Por exemplo:
SELECT*-- Same as beforeFROM 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 createdJOIN departments AS d ON day >= d.created_at
Observe que a palavra INNER- chave é opcional (exceto no MS Access).
Um tipo especial de Theta-JOIN é o equi JOIN, que mais usamos. O predicado associa a chave primária de uma tabela à chave estrangeira de outra tabela. Se usarmos o banco 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
Isso combina todos os atores com seus filmes.
Ou também, em alguns bancos de dados:
SELECT*FROM actor
JOIN film_actor USING(actor_id)JOIN film USING(film_id)
A USING()sintaxe permite especificar uma coluna que deve estar presente em ambos os lados das tabelas de uma operação JOIN e cria um predicado de igualdade nessas duas colunas.
JUNÇÃO NATURAL
Outras respostas listaram esse "tipo JOIN" separadamente, mas isso não faz sentido. É apenas uma forma de açúcar de sintaxe para o equi JOIN, que é um caso especial de Theta-JOIN ou INNER JOIN. NATURAL JOIN simplesmente coleta todas as colunas comuns às duas tabelas que estão sendo unidas e une USING()essas colunas. O que quase nunca é útil, devido a correspondências acidentais (como LAST_UPDATEcolunas no banco de dados Sakila ).
Aqui está a sintaxe:
SELECT*FROM actor
NATURALJOIN film_actor
NATURALJOIN film
JUNÇÃO EXTERNA
Agora, OUTER JOINé um pouco diferente INNER JOIN, pois cria um UNIONdos vários produtos cartesianos. Nós podemos escrever:
-- Convenient syntax:SELECT*FROM a LEFTJOIN b ON<predicate>-- Cumbersome, equivalent syntax:SELECT a.*, b.*FROM a JOIN b ON<predicate>UNIONALLSELECT a.*,NULL,NULL,...,NULLFROM a
WHERENOTEXISTS(SELECT*FROM b WHERE<predicate>)
Ninguém quer escrever o último, então escrevemos OUTER JOIN(o que geralmente é melhor otimizado pelos bancos de dados).
Como INNER, a palavra OUTER- chave é opcional aqui.
OUTER JOIN vem em três sabores:
LEFT [ OUTER ] JOIN: A tabela esquerda da JOINexpressão é adicionada à união, como mostrado acima.
RIGHT [ OUTER ] JOIN: A tabela direita da JOINexpressão é adicionada à união, como mostrado acima.
FULL [ OUTER ] JOIN: As duas tabelas da JOINexpressão são adicionadas à união, como mostrado acima.
Existem algumas sintaxes obsoletas e históricas no Oracle e SQL Server, que OUTER JOINjá eram suportadas antes do padrão SQL ter uma sintaxe para isso:
-- OracleSELECT*FROM actor a, film_actor fa, film f
WHERE a.actor_id = fa.actor_id(+)AND fa.film_id = f.film_id(+)-- SQL ServerSELECT*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 listo isso aqui para que você possa reconhecê-lo em postagens antigas / código legado.
Particionado OUTER JOIN
Poucas pessoas sabem disso, mas o padrão SQL especifica particionado OUTER JOIN(e a Oracle o implementa). Você pode escrever coisas assim:
WITH-- Using CONNECT BY to generate all dates in January
days(day)AS(SELECT DATE '2017-01-01'+ LEVEL -1FROM dual
CONNECTBY LEVEL <=31),-- Our departments
departments(department, created_at)AS(SELECT'Dept 1', DATE '2017-01-10'FROM dual UNIONALLSELECT'Dept 2', DATE '2017-01-11'FROM dual UNIONALLSELECT'Dept 3', DATE '2017-01-12'FROM dual UNIONALLSELECT'Dept 4', DATE '2017-04-01'FROM dual UNIONALLSELECT'Dept 5', DATE '2017-04-02'FROM dual
)SELECT*FROM days
LEFTJOIN departments
PARTITIONBY(department)-- This is where the magic happensON day >= created_at
Partes do 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 serão encerradas no resultado, independentemente se houver JOINalguma correspondência no "outro lado da junção". Longa história: é para preencher dados esparsos nos relatórios. Muito útil!
SEMI JOIN
Seriamente? Nenhuma outra resposta conseguiu isso? Claro que não, porque infelizmente não possui uma sintaxe nativa no SQL (como ANTI JOIN abaixo). Mas podemos usar IN()e EXISTS(), por exemplo, encontrar todos os atores que atuaram nos filmes:
SELECT*FROM actor a
WHEREEXISTS(SELECT*FROM film_actor fa
WHERE a.actor_id = fa.actor_id
)
O WHERE a.actor_id = fa.actor_idpredicado atua como o predicado de semi-junção. Se você não acredita, consulte os planos de execução, por exemplo, no Oracle. Você verá que o banco de dados executa uma operação SEMI JOIN, não o EXISTS()predicado.
SELECT*FROM actor a
WHERENOTEXISTS(SELECT*FROM film_actor fa
WHERE a.actor_id = fa.actor_id
)
Algumas pessoas (especialmente as pessoas do MySQL) também escrevem ANTI JOIN assim:
SELECT*FROM actor a
LEFTJOIN film_actor fa
USING(actor_id)WHERE film_id ISNULL
Eu acho que a razão histórica é desempenho.
INSCRIÇÃO LATERAL
OMG, este é muito legal. Eu sou o único a mencionar isso? Aqui está uma consulta interessante:
SELECT a.first_name, a.last_name, f.*FROM actor AS a
LEFTOUTERJOIN 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!GROUPBY f.film_id
ORDERBY revenue DESC
LIMIT 5)AS f
ON true
Ele encontrará os 5 principais filmes produtores de receita por ator. Toda vez que você precisar de uma consulta TOP-N-por-algo, LATERAL JOINserá seu amigo. Se você é uma pessoa do SQL Server, conhece esse JOINtipo com o nomeAPPLY
SELECT a.first_name, a.last_name, f.*FROM actor AS a
OUTERAPPLY(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!GROUPBY f.film_id
ORDERBY revenue DESC
LIMIT 5)AS f
OK, talvez isso seja trapaça, porque uma expressão LATERAL JOINou APPLYé realmente uma "subconsulta correlacionada" que produz várias linhas. Mas se permitirmos "subconsultas correlacionadas", também poderemos falar sobre ...
MULTISET
Isso é realmente implementado apenas pelo Oracle e Informix (que eu saiba), mas pode ser emulado no PostgreSQL usando matrizes e / ou XML e no SQL Server usando XML.
MULTISETproduz uma subconsulta correlacionada e aninha o conjunto de linhas resultante na consulta externa. A consulta abaixo seleciona todos os atores e, para cada ator, coleta 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 você viu, existem mais tipos de Cadastre-se que apenas o "chato" INNER, OUTERe CROSS JOINque normalmente são mencionados. Mais detalhes no meu artigo . E, por favor, pare de usar os diagramas de Venn para ilustrá-los.
Equijoin é o caso especial de junção teta, onde teta é igualdade. A junção teta é análoga a um caso especial de junção interna, onde on é uma comparação teta de uma coluna de cada uma. Algumas décadas depois que o Codd os definiu, alguns livros didáticos definiram mal a junção teta como uma generalização que é o análogo da junção interna.
philipxy
@ philipxy: Alguma coisa específica que eu deva mudar na minha resposta? Você pode sugerir uma edição ...
Lukas Eder
10
Eu criei uma ilustração que explica melhor do que palavras, na minha opinião:
@Niraj Os círculos A e B não contêm as linhas de A e B. Eles são copiados cegamente de outro lugar sem crédito. A junção cruzada é incluída no caso de junção interna, é junção interna em 1 = 1. De que maneira essas partes da imagem são "perfeitas"?
Philipxy # 6/18
@ philipxy Desculpe, mas não me preocupo se for copiado de outro lugar. e não tenho certeza do que não está correto na imagem acima. para mim está tudo bem. A junção cruzada não é descrita aqui. Não está incluído em uma junção interna ..
Niraj 08/08
-3
Vou empurrar minha irritação: a palavra-chave USING.
Se ambas as tabelas nos dois lados do JOIN tiverem suas chaves estrangeiras nomeadas corretamente (ou seja, mesmo nome, não apenas "id"), isso poderá ser usado:
O que é
SQL JOIN
?SQL JOIN
é um método para recuperar dados de duas ou mais tabelas de banco de dados.Quais são os diferentes
SQL JOIN
s?Há um total de cinco
JOIN
s. Eles são :1. JOIN ou INNER JOIN:
Nesse tipo de a
JOIN
, obtemos todos os registros que correspondem à condição nas duas tabelas e os registros nas duas tabelas que não correspondem não são relatados.Em outras palavras,
INNER JOIN
é baseado no fato único de que: SOMENTE as entradas correspondentes em AMBAS as tabelas DEVEM ser listadas.Note-se que um
JOIN
sem quaisquer outrasJOIN
palavras-chave (comoINNER
,OUTER
,LEFT
, etc) é umINNER JOIN
. Em outras palavras,JOIN
é um açúcar sintático paraINNER JOIN
(consulte: Diferença entre JOIN e INNER JOIN ).2. JUNÇÃO EXTERNA:
OUTER JOIN
recuperaAs linhas correspondentes de uma tabela e todas as linhas da outra tabela. Ou todas as linhas de todas as tabelas (não importa se existe ou não uma correspondência).
Existem três tipos de junção externa:
2.1 JOGO EXTERIOR ESQUERDO ou JOIN ESQUERDO
Essa junção retorna todas as linhas da tabela esquerda em conjunto com as linhas correspondentes da tabela direita. Se não houver colunas correspondentes na tabela à direita, ele retornará
NULL
valores.2.2 JUNÇÃO EXTERNA DIREITA ou JUNTA DIREITA
Isso
JOIN
retorna todas as linhas da tabela direita em conjunto com as linhas correspondentes da tabela esquerda. Se não houver colunas correspondentes na tabela esquerda, ele retornaráNULL
valores.2.3 JUNÇÃO EXTERNA COMPLETA ou JUNÇÃO COMPLETA
Isso
JOIN
combinaLEFT OUTER JOIN
eRIGHT OUTER JOIN
. Retorna linhas de qualquer tabela quando as condições são atendidas e retornaNULL
valor quando não há correspondência.Em outras palavras,
OUTER JOIN
é baseado no fato de que: SOMENTE as entradas correspondentes em UMA DAS tabelas (DIREITA ou ESQUERDA) ou AMBAS as tabelas (CHEIA) DEVEM ser listadas.3. JUNÇÃO NATURAL:
É baseado nas duas condições:
JOIN
é feito em todas as colunas com o mesmo nome para igualdade.Isso parece ser mais de natureza teórica e, como resultado (provavelmente), a maioria dos DBMS nem se dá ao trabalho de apoiar isso.
4. JUNÇÃO TRANSVERSAL:
É o produto cartesiano das duas tabelas envolvidas. O resultado de a
CROSS JOIN
não fará sentido na maioria das situações. Além disso, não precisaremos disso (ou precisa, no mínimo, para ser mais preciso).5. AUTO-JUNÇÃO:
Não é uma forma diferente de
JOIN
, pelo contrário, é umJOIN
(INNER
,OUTER
, etc.) de uma mesa para si.JOINs com base em operadores
Dependendo do operador usado para uma
JOIN
cláusula, pode haver dois tipos deJOIN
s. Eles são1. Equi JOIN:
Para qualquer
JOIN
tipo (INNER
,OUTER
etc), se usarmos SOMENTE o operador de igualdade (=), então dizemos queJOIN
é umEQUI JOIN
.2. Theta JOIN:
É o mesmo,
EQUI JOIN
mas permite todos os outros operadores como>, <,> = etc.fonte
Definição:
JOINS são uma maneira de consultar os dados combinados de várias tabelas simultaneamente.
Tipos de JOINS:
No que diz respeito ao RDBMS, existem 5 tipos de junções:
Equi-Join: combina registros comuns de duas tabelas com base na condição de igualdade. Tecnicamente, a Junta é feita usando o operador de igualdade (=) para comparar os valores da Chave Primária de uma tabela e da Chave Externa de outra tabela; portanto, o conjunto de resultados inclui registros comuns (correspondentes) das duas tabelas. Para implementação, consulte INNER-JOIN.
Junção natural: é uma versão aprimorada do Equi-Join, na qual a operação SELECT omite a coluna duplicada. Para implementação, consulte INNER-JOIN
Non-Equi-Join: É o inverso da Equi-join onde a condição de junção é diferente de operador igual (=), por exemplo,! =, <=,> =,>, <Ou ENTRE etc. Para implementação, consulte INNER-JOIN.
Auto- ingresso:: um comportamento personalizado de ingresso em que uma tabela se combina consigo mesma; Isso geralmente é necessário para consultar tabelas de auto-referência (ou entidade de relacionamento Unário). Para implementação, consulte INNER-JOINs.
Produto cartesiano: Cruz combina todos os registros de ambas as tabelas sem nenhuma condição. Tecnicamente, ele retorna o conjunto de resultados de uma consulta sem a cláusula WHERE.
De acordo com a preocupação e o avanço do SQL, existem três tipos de junções e todas as junções RDBMS podem ser obtidas usando esses tipos de junções.
INNER-JOIN: Mescla (ou combina) 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 igualdade, então: EQUI-JOIN for executada, caso contrário, não-EQUI-Join.
OUTER-JOIN: mescla (ou combina) linhas correspondentes de duas tabelas e linhas não correspondentes com valores NULL. No entanto, é possível customizar a seleção de linhas sem correspondência, por exemplo, selecionando a linha sem correspondência da primeira tabela ou da segunda tabela por sub-tipos: JUNÇÃO EXTERNA ESQUERDA e JUNÇÃO EXTERNA DIREITA.
2.1 LEFT Outer JOIN (também conhecido como LEFT-JOIN): Retorna linhas correspondentes de duas tabelas e não correspondentes da tabela LEFT (ou seja, primeira tabela).
2.2 JOIN externo à direita (também conhecido como JOINT à DIREITA): retorna linhas correspondentes de duas tabelas e não correspondentes apenas da tabela RIGHT.
2.3 JOGO EXTERNO COMPLETO (também conhecido como JOIN EXTERIOR): Retorna correspondidos e não correspondidos das duas tabelas.
CROSS-JOIN: Essa junção não mescla / combina, em vez disso, executa o produto cartesiano.
Nota: A auto-junção pode ser alcançada por INNER-JOIN, OUTER-JOIN e CROSS-JOIN com base no requisito, mas a tabela deve se unir.
Para maiores informações:
Exemplos:
1.1: INNER-JOIN: Implementação de Equi-join
1.2: INNER-JOIN: Implementação Natural-JOIN
1.3: INNER-JOIN com implementação NÃO-Equi-join
1.4: INNER-JOIN com SELF-JOIN
2.1: JUNÇÃO EXTERNA (junção externa completa)
2.2: JUNTA ESQUERDA
2.3: JUNTA CERTA
3.1: JUNÇÃO TRANSVERSAL
3.2: CROSS JOIN-Self JOIN
//OU//
fonte
intersect
/except
/union
; aqui os círculos são as linhas retornadas porleft
&right
join
, como dizem os rótulos numerados. A imagem do AXB não faz sentido.cross join
=inner join on 1=1
& é um caso especial do primeiro diagrama.UNION JOIN
. Agora tornado obsoleto no SQL: 2003.Curiosamente, a maioria das outras respostas sofre com esses dois problemas:
Escrevi recentemente um artigo sobre o tópico: Um guia abrangente e provavelmente incompleto para as várias maneiras diferentes de ingressar em tabelas no SQL , que resumirei aqui.
Em primeiro lugar: JUNTAS são produtos cartesianos
É por isso que os diagramas de Venn os explicam de maneira tão imprecisa, porque um JOIN cria um produto cartesiano entre as duas tabelas unidas. A Wikipedia ilustra bem:
A sintaxe SQL para produtos cartesianos é
CROSS JOIN
. Por exemplo:Que combina todas as linhas de uma tabela com todas as linhas da outra tabela:
Fonte:
Resultado:
Se apenas escrevermos uma lista de tabelas separadas por vírgula, obteremos o mesmo:
INNER JOIN (Theta-JOIN)
An
INNER JOIN
é apenas um filtroCROSS JOIN
onde o predicado de filtro é chamadoTheta
na álgebra relacional.Por exemplo:
Observe que a palavra
INNER
- chave é opcional (exceto no MS Access).( veja o artigo para exemplos de resultados )
EQUI JOIN
Um tipo especial de Theta-JOIN é o equi JOIN, que mais usamos. O predicado associa a chave primária de uma tabela à chave estrangeira de outra tabela. Se usarmos o banco de dados Sakila para ilustração, podemos escrever:
Isso combina todos os atores com seus filmes.
Ou também, em alguns bancos de dados:
A
USING()
sintaxe permite especificar uma coluna que deve estar presente em ambos os lados das tabelas de uma operação JOIN e cria um predicado de igualdade nessas duas colunas.JUNÇÃO NATURAL
Outras respostas listaram esse "tipo JOIN" separadamente, mas isso não faz sentido. É apenas uma forma de açúcar de sintaxe para o equi JOIN, que é um caso especial de Theta-JOIN ou INNER JOIN. NATURAL JOIN simplesmente coleta todas as colunas comuns às duas tabelas que estão sendo unidas e une
USING()
essas colunas. O que quase nunca é útil, devido a correspondências acidentais (comoLAST_UPDATE
colunas no banco de dados Sakila ).Aqui está a sintaxe:
JUNÇÃO EXTERNA
Agora,
OUTER JOIN
é um pouco diferenteINNER JOIN
, pois cria umUNION
dos vários produtos cartesianos. Nós podemos escrever:Ninguém quer escrever o último, então escrevemos
OUTER JOIN
(o que geralmente é melhor otimizado pelos bancos de dados).Como
INNER
, a palavraOUTER
- chave é opcional aqui.OUTER JOIN
vem em três sabores:LEFT [ OUTER ] JOIN
: A tabela esquerda daJOIN
expressão é adicionada à união, como mostrado acima.RIGHT [ OUTER ] JOIN
: A tabela direita daJOIN
expressão é adicionada à união, como mostrado acima.FULL [ OUTER ] JOIN
: As duas tabelas daJOIN
expressão são adicionadas à união, como mostrado acima.Tudo isso pode ser combinado com a palavra-chave
USING()
ou comNATURAL
( na verdade, tiveNATURAL FULL JOIN
recentemente um caso de uso do mundo real )Sintaxe alternativa
Existem algumas sintaxes obsoletas e históricas no Oracle e SQL Server, que
OUTER JOIN
já eram suportadas antes do padrão SQL ter uma sintaxe para isso:Dito isto, não use esta sintaxe. Eu apenas listo isso aqui para que você possa reconhecê-lo em postagens antigas / código legado.
Particionado
OUTER JOIN
Poucas pessoas sabem disso, mas o padrão SQL especifica particionado
OUTER JOIN
(e a Oracle o implementa). Você pode escrever coisas assim:Partes do resultado:
O ponto aqui é que todas as linhas do lado particionado da junção serão encerradas no resultado, independentemente se houver
JOIN
alguma correspondência no "outro lado da junção". Longa história: é para preencher dados esparsos nos relatórios. Muito útil!SEMI JOIN
Seriamente? Nenhuma outra resposta conseguiu isso? Claro que não, porque infelizmente não possui uma sintaxe nativa no SQL (como ANTI JOIN abaixo). Mas podemos usar
IN()
eEXISTS()
, por exemplo, encontrar todos os atores que atuaram nos filmes:O
WHERE a.actor_id = fa.actor_id
predicado atua como o predicado de semi-junção. Se você não acredita, consulte os planos de execução, por exemplo, no Oracle. Você verá que o banco de dados executa uma operação SEMI JOIN, não oEXISTS()
predicado.ANTI JOIN
Este é exatamente o oposto do SEMI JOIN ( ter cuidado para não usar
NOT IN
embora , já que tem uma importante advertência)Aqui estão todos os atores sem filmes:
Algumas pessoas (especialmente as pessoas do MySQL) também escrevem ANTI JOIN assim:
Eu acho que a razão histórica é desempenho.
INSCRIÇÃO LATERAL
OMG, este é muito legal. Eu sou o único a mencionar isso? Aqui está uma consulta interessante:
Ele encontrará os 5 principais filmes produtores de receita por ator. Toda vez que você precisar de uma consulta TOP-N-por-algo,
LATERAL JOIN
será seu amigo. Se você é uma pessoa do SQL Server, conhece esseJOIN
tipo com o nomeAPPLY
OK, talvez isso seja trapaça, porque uma expressão
LATERAL JOIN
ouAPPLY
é realmente uma "subconsulta correlacionada" que produz várias linhas. Mas se permitirmos "subconsultas correlacionadas", também poderemos falar sobre ...MULTISET
Isso é realmente implementado apenas pelo Oracle e Informix (que eu saiba), mas pode ser emulado no PostgreSQL usando matrizes e / ou XML e no SQL Server usando XML.
MULTISET
produz uma subconsulta correlacionada e aninha o conjunto de linhas resultante na consulta externa. A consulta abaixo seleciona todos os atores e, para cada ator, coleta seus filmes em uma coleção aninhada:Como você viu, existem mais tipos de Cadastre-se que apenas o "chato"
INNER
,OUTER
eCROSS JOIN
que normalmente são mencionados. Mais detalhes no meu artigo . E, por favor, pare de usar os diagramas de Venn para ilustrá-los.fonte
Eu criei uma ilustração que explica melhor do que palavras, na minha opinião:
fonte
Vou empurrar minha irritação: a palavra-chave USING.
Se ambas as tabelas nos dois lados do JOIN tiverem suas chaves estrangeiras nomeadas corretamente (ou seja, mesmo nome, não apenas "id"), isso poderá ser usado:
Acho isso muito prático, legível e não usado com frequência.
fonte