sql >> Base de Datos >  >> RDS >> Oracle

Uniones izquierda y derecha usando el signo más (+) en Oracle

  • ¿Qué es una unión interna?
  • ¿Qué es una combinación externa?
    • Realización de uniones externas con el símbolo (+)

Como prácticamente todas las bases de datos relacionales, Oracle permite generar consultas que combinan o JOIN filas de dos o más tablas para crear el conjunto de resultados final. Si bien existen numerosos tipos de uniones que se pueden realizar, las más comunes son las INNER JOIN y la OUTER JOIN .

En este tutorial, exploraremos brevemente la diferencia entre el INNER y OUTER JOIN y luego examine el método abreviado que proporciona Oracle para realizar OUTER JOINS específicamente usando el + símbolo del operador.

¿Qué es una unión interna?

Una INNER JOIN en una base de datos relacional es simplemente la unión de dos o más tablas en las que el resultado solo contendrá datos que satisfagan todas las condiciones de unión .

Por ejemplo, aquí tenemos una library básica esquema con dos tablas:books y languages . Los languages la tabla es solo una lista de posibles nombres de idiomas y un idioma único 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

Mientras tanto, nuestros books la tabla tiene un language_id fila que para la mayoría de los libros, pero no para todos, simplemente contiene el language_id asociado con el idioma original publicado del libro:

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

En muchos casos, es posible que deseemos realizar una INNER JOIN de los books y languages tablas por lo que en lugar de ver el sin sentido language_id valor de cada libro, en realidad podemos ver el language name en su lugar.

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

Lo que es fundamental tener en cuenta aquí es que nuestro conjunto de resultados fue ligeramente diferente en las dos consultas anteriores. En el primero, simplemente enumeramos el primer 10 libros, pero en el INNER JOIN consulta, solo devolvemos resultados que cumplen todas las condiciones de ambas tablas. Por ello, el registro de Hamlet (que tiene un language_id valor de null o vacío) se ignora y no se devuelve en el resultado de nuestro INNER JOIN .

¿Qué es una unión externa?

En lugar de devolver exclusivamente resultados que satisfagan todas las condiciones de unión de una INNER JOIN , una OUTER JOIN devuelve no solo resultados que satisfacen todas las condiciones, sino también devuelve las filas de una tabla que no cumplieron la condición. La tabla que se elige para esta "omisión" de los requisitos condicionales está determinada por la direccionalidad o el "lado" de la combinación, normalmente denominada LEFT o RIGHT uniones externas.

Al definir un lado de su OUTER JOIN , está especificando qué tabla siempre devolverá su fila incluso si el opuesto falta la tabla en el otro lado de la combinación o null valores como parte de la condición de unión.

Por lo tanto, si realizamos el mismo JOIN básico como arriba para recuperar books y language names , sabemos que nuestros books la tabla siempre debe devolver datos, por lo que nuestro JOIN el lado debe "apuntar hacia" nuestros books tabla, lo que hace que los languages tabla el OUTER tabla que le adjuntamos.

Para lograr esto, simplemente cambiamos:

books b INNER JOIN library.languages l

…a esto:

books b LEFT OUTER JOIN library.languages l

Por lo tanto, toda la consulta y el conjunto de resultados se ven casi idénticos a INNER JOIN excepto esa alteración menor:

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 era de esperar, mediante el uso de LEFT OUTER JOIN en lugar del anterior INNER JOIN , obtenemos lo mejor de ambos mundos:no nos saltamos ningún books registros (como Hamlet ) simplemente porque el language_id el valor es null para ese registro, pero para todos los registros donde language_id existe, obtenemos el language name bien formateado obtenido de nuestros languages mesa.

Realizar uniones externas usando el símbolo (+)

Como se indica en la documentación oficial, Oracle proporciona un outer join operator especial (el + símbolo) que es una forma abreviada de realizar OUTER JOINS .

En la práctica, el + el símbolo se coloca directamente en el condicional declaración y en el lado de la tabla opcional (la que puede contener vacío o null valores dentro del condicional).

Por lo tanto, podemos volver a escribir nuestra anterior LEFT OUTER JOIN declaración usando el + operador así:

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;

Los resultados son los mismos que los de LEFT OUTER JOIN estándar ejemplo anterior, por lo que no los incluiremos aquí. Sin embargo, hay un aspecto crítico a tener en cuenta sobre la sintaxis usando + operador para OUTER JOINS .

El + el operador debe estar en el lado izquierdo del condicional (a la izquierda de los iguales = señal). Por lo tanto, en este caso, porque queremos asegurarnos de que nuestros languages table es la tabla opcional que puede devolver null valores durante esta comparación, intercambiamos el orden de las tablas en este condicional, por lo que languages está a la izquierda (y es opcional) mientras que books está a la derecha.

Por último, debido a este reordenamiento de los lados de la tabla en el condicional cuando se usa + operador, es importante darse cuenta de que lo anterior es simplemente una abreviatura de RIGHT OUTER JOIN . Esto significa que este fragmento de la consulta:

FROM
  books b,
  library.languages l
WHERE
  l.id (+)= b.language_id

…es efectivamente idéntico a esto:

FROM
  library.languages l
RIGHT OUTER JOIN
  books b
ON
  b.language_id = l.id