Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

Junções Esquerda e Direita Usando o Sinal de Mais (+) no Oracle

  • O que é uma Inner Join?
  • O que é uma junção externa?
    • Executando junções externas usando o símbolo (+)

Como praticamente todos os bancos de dados relacionais, o Oracle permite a geração de consultas que combinam ou JOIN linhas de duas ou mais tabelas para criar o conjunto de resultados final. Embora existam vários tipos de junções que podem ser realizadas, as mais comuns são as INNER JOIN e o OUTER JOIN .

Neste tutorial, exploraremos brevemente a diferença entre o INNER e OUTER JOIN e, em seguida, examine o método abreviado que o Oracle fornece para executar OUTER JOINS especificamente usando o + símbolo do operador.

O que é uma Inner Join?


Um INNER JOIN em um banco de dados relacional é simplesmente a junção de duas ou mais tabelas em que o resultado contém apenas dados que satisfaçam todas as condições de junção .

Por exemplo, aqui temos uma library básica esquema com duas tabelas:books e languages . Os languages table é apenas uma lista de nomes de idiomas possíveis e um idioma exclusivo id :
SELECT * FROM library.languages;

id   name
1   English
2   French
3   German
4   Mandarin
5   Spanish
6   Arabic
7   Japanese
8   Russian
9   Greek
10   Italian

Enquanto isso, nossos books tabela tem um language_id linha que para a maioria dos livros, mas não todos, simplesmente contém o language_id associado ao idioma original publicado do livro:
SELECT * FROM
  books
ORDER BY
  id
FETCH FIRST 10 ROWS ONLY;

id title    author    year_published    language_id
1   In Search of Lost Time  Marcel Proust   1913    2
2   Ulysses James Joyce 1922    1
3   Don Quixote Miguel de Cervantes 1605    5
4   Moby Dick   Herman Melville 1851    1
5   Hamlet  William Shakespeare 1601 (null)
6   War and Peace   Leo Tolstoy 1869    8
7   The Odyssey Homer   -700    9
8   The Great Gatsby    F. Scott Fitzgerald 1925    1
9   The Divine Comedy   Dante Alighieri     1472    10
10  Madame Bovary   Gustave Flaubert    1857    2

Em muitos casos, podemos desejar realizar um INNER JOIN dos books e languages tabelas, em vez de visualizar o language_id sem sentido valor de cada livro, podemos ver o language name em vez de.
SELECT
  b.id,
  b.title,
  b.author,
  b.year_published,
  l.name language
FROM
  books b
INNER JOIN
  library.languages l
ON
  b.language_id = l.id
ORDER BY
  b.id
FETCH FIRST 10 ROWS ONLY;

id title    author    year_published    language
1   In Search of Lost Time  Marcel Proust   1913    French
2   Ulysses James Joyce 1922    English
3   Don Quixote Miguel de Cervantes 1605    Spanish
4   Moby Dick   Herman Melville 1851    English
6   War and Peace   Leo Tolstoy 1869    Russian
7   The Odyssey Homer   -700    Greek
8   The Great Gatsby    F. Scott Fitzgerald 1925    English
9   The Divine Comedy   Dante Alighieri     1472    Italian
10  Madame Bovary   Gustave Flaubert    1857    French
11  The Brothers Karamazov  Fyodor Dostoyevsky  1880    Russian

O que é fundamental observar aqui é que nosso conjunto de resultados foi um pouco diferente nas duas consultas acima. No primeiro, simplesmente listamos os primeiros 10 livros, mas no INNER JOIN query, estamos retornando apenas resultados que atendem a todas as condições de ambas as tabelas. Por esta razão, o registro de Hamlet (que tem um language_id valor de null ou vazio) é ignorado e não retornado no resultado do nosso INNER JOIN .

O que é uma Outer Join?


Em vez de retornar exclusivamente resultados que satisfaçam todas as condições de junção de um INNER JOIN , um OUTER JOIN retorna não apenas resultados que satisfazem todas as condições, mas também retorna linhas de uma tabela que não satisfez a condição. A tabela que é escolhida para este “bypass” de requisitos condicionais é determinada pela direcionalidade ou “lado” da junção, normalmente chamada de LEFT ou RIGHT juntas externas.

Ao definir um lado para seu OUTER JOIN , você está especificando qual tabela sempre retornará sua linha mesmo que a oposta a tabela do outro lado da junção está ausente ou null valores como parte da condição de junção.

Portanto, se executarmos o mesmo JOIN básico como acima para recuperar books e language names , sabemos que nossos books tabela deve sempre retornar dados, então nosso JOIN lado deve "apontar para" nossos books tabela, tornando assim os languages tabela o OUTER tabela que estamos anexando a ela.

Para isso, basta alterar:
books b INNER JOIN library.languages l

…para isso:
books b LEFT OUTER JOIN library.languages l

Assim, toda a consulta e o conjunto de resultados parecem quase idênticos ao INNER JOIN exceto essa pequena alteração:
SELECT
  b.id,
  b.title,
  b.author,
  b.year_published,
  l.name language
FROM
  books b
LEFT OUTER JOIN
  library.languages l
ON
  b.language_id = l.id
ORDER BY
  b.id
FETCH FIRST 10 ROWS ONLY;

id title    author    year_published    language
1   In Search of Lost Time  Marcel Proust   1913    French
2   Ulysses James Joyce 1922    English
3   Don Quixote Miguel de Cervantes 1605    Spanish
4   Moby Dick   Herman Melville 1851    English
5   Hamlet  William Shakespeare 1601  (null)
6   War and Peace   Leo Tolstoy 1869    Russian
7   The Odyssey Homer   -700    Greek
8   The Great Gatsby    F. Scott Fitzgerald 1925    English
9   The Divine Comedy   Dante Alighieri     1472    Italian
10  Madame Bovary   Gustave Flaubert    1857    French

Como esperado, usando um LEFT OUTER JOIN em vez do anterior INNER JOIN , estamos obtendo o melhor dos dois mundos:não vamos pular nenhum books registros (como Hamlet ) simplesmente porque o language_id valor é null para esse registro, mas para todos os registros em que language_id existe, obtemos o language name bem formatado obtido de nossos languages tabela.

Executando junções externas usando o símbolo (+)


Conforme indicado na documentação oficial, a Oracle fornece um outer join operator especial (o + símbolo) que é uma abreviação para executar OUTER JOINS .

Na prática, o + símbolo é colocado diretamente na condicional e no lado da tabela opcional (aquela que pode conter valores vazios ou null valores dentro da condicional).

Portanto, podemos mais uma vez reescrever nosso LEFT OUTER JOIN acima declaração usando o + operador assim:
SELECT
  b.id,
  b.title,
  b.author,
  b.year_published,
  l.name language
FROM
  books b,
  library.languages l
WHERE
  l.id (+)= b.language_id
ORDER BY
  b.id
FETCH FIRST 10 ROWS ONLY;

Os resultados são os mesmos que o padrão LEFT OUTER JOIN exemplo acima, então não vamos incluí-los aqui. No entanto, há um aspecto crítico a ser observado sobre a sintaxe usando o + operador para OUTER JOINS .

O + operador deve estar no lado esquerdo da condicional (à esquerda do igual a = sinal). Portanto, neste caso, porque queremos garantir que nossos languages table é a tabela opcional que pode retornar null valores durante esta comparação, trocamos a ordem das tabelas nesta condicional, então languages está à esquerda (e é opcional) enquanto books está à direita.

Por fim, devido a essa reordenação dos lados da tabela na condicional ao usar o + operador, é importante perceber que o acima é simplesmente um atalho para um RIGHT OUTER JOIN . Isso significa que este snippet da consulta:
FROM
  books b,
  library.languages l
WHERE
  l.id (+)= b.language_id

…é efetivamente idêntico a isso:
FROM
  library.languages l
RIGHT OUTER JOIN
  books b
ON
  b.language_id = l.id