Autounion de tablas en Oracle

Cuando trabajas con modelos relacionales, no siempre necesitas cruzar información entre dos tablas distintas. En ocasiones, lo que necesitas es comparar datos dentro de una misma tabla. En estos casos, lo que se utiliza es una autounión de tablas en Oracle, también conocida como self join.

En este artículo voy a explicarte qué es una autounión, cuándo se utiliza y cómo puedes implementarla en Oracle 23ai. Primero veremos la sintaxis básica y después repasaremos varios ejemplos con casos reales y estructuras sencillas para que lo entiendas al vuelo.

Autounion de tablas en Oracle

Una autounión es una operación JOIN en la que una tabla se une consigo misma. Aunque suene extraño, tiene mucho sentido: lo que haces es comparar diferentes filas de la misma tabla como si fueran entidades distintas. Para que funcione, necesitas asignar alias diferentes a la misma tabla dentro de la misma consulta.

Sintaxis básica

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
SELECT ...
FROM tabla t1
JOIN tabla t2 ON condiciones_de_comparación;
SELECT ... FROM tabla t1 JOIN tabla t2 ON condiciones_de_comparación;
SELECT ...
FROM tabla t1
JOIN tabla t2 ON condiciones_de_comparación;

En este patrón, t1 y t2 son alias distintos de la misma tabla, lo que te permite referenciar diferentes filas como si vinieran de tablas separadas.

Ejemplo 1: empleados y jefes

Supongamos que tienes una tabla empleados con esta estructura:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
CREATE TABLE empleados (
id_empleado NUMBER,
nombre VARCHAR2(50),
id_jefe NUMBER
);
CREATE TABLE empleados ( id_empleado NUMBER, nombre VARCHAR2(50), id_jefe NUMBER );
CREATE TABLE empleados (
    id_empleado       NUMBER,
    nombre            VARCHAR2(50),
    id_jefe           NUMBER
);

Y los siguientes datos…

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
INSERT INTO empleados VALUES (1, 'Miguel', NULL);
INSERT INTO empleados VALUES (2, 'Ismael', 1);
INSERT INTO empleados VALUES (3, 'Pilar', 1);
INSERT INTO empleados VALUES (4, 'Laura', 2);
INSERT INTO empleados VALUES (1, 'Miguel', NULL); INSERT INTO empleados VALUES (2, 'Ismael', 1); INSERT INTO empleados VALUES (3, 'Pilar', 1); INSERT INTO empleados VALUES (4, 'Laura', 2);
INSERT INTO empleados VALUES (1, 'Miguel', NULL);
INSERT INTO empleados VALUES (2, 'Ismael', 1);
INSERT INTO empleados VALUES (3, 'Pilar', 1);
INSERT INTO empleados VALUES (4, 'Laura', 2);

Aquí puedes ver que algunos empleados tienen un id_jefe que apunta al id_empleado de otro compañero. Para obtener una lista de empleados junto al nombre de su jefe, usarías una autounión así:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
SELECT e.nombre AS nombre_empleado,
j.nombre AS nombre_jefe
FROM empleados e
LEFT JOIN empleados j ON e.id_jefe = j.id_empleado;
SELECT e.nombre AS nombre_empleado, j.nombre AS nombre_jefe FROM empleados e LEFT JOIN empleados j ON e.id_jefe = j.id_empleado;
SELECT e.nombre AS nombre_empleado,
       j.nombre AS nombre_jefe
FROM empleados e
LEFT JOIN empleados j ON e.id_jefe = j.id_empleado;

¿Qué devuelve esta consulta?

Este LEFT JOIN compara cada fila de la tabla empleados (e) con otras filas de la misma tabla (j) buscando coincidencias entre id_jefe y id_empleado. El resultado es algo así:

Ejemplo 2: comparar fechas entre registros

Imagina que tienes una tabla eventos con registros que tienen una fecha y quieres comparar cada evento con otros para ver cuál ocurrió antes. Aquí también puedes usar una autounión:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
SELECT e1.nombre AS evento_actual,
e2.nombre AS evento_anterior
FROM eventos e1
JOIN eventos e2 ON e1.fecha > e2.fecha;
SELECT e1.nombre AS evento_actual, e2.nombre AS evento_anterior FROM eventos e1 JOIN eventos e2 ON e1.fecha > e2.fecha;
SELECT e1.nombre AS evento_actual,
       e2.nombre AS evento_anterior
FROM eventos e1
JOIN eventos e2 ON e1.fecha > e2.fecha;

Esto devuelve todas las combinaciones posibles en las que un evento ocurrió después que otro. Puedes filtrar o agrupar según lo que quieras conseguir.

Consejos

  • Siempre usa alias diferentes para no volverte loco con los nombres de columna.
  • Añade filtros como WHERE o LIMIT si la tabla es grande. Las autouniones pueden devolver muchas combinaciones.
  • No todas las autouniones necesitan INNER JOIN. A veces un LEFT JOIN es lo más útil para detectar registros sin correspondencia (como empleados sin jefe).

Escribir un comentario