45 - Unión

El operador "union" combina el resultado de dos o más instrucciones "select" en un único resultado.

Se usa cuando los datos que se quieren obtener pertenecen a distintas tablas y no se puede acceder a ellos con una sola consulta.

Es necesario que las tablas referenciadas tengan tipos de datos similares, la misma cantidad de campos y el mismo orden de campos en la lista de selección de cada consulta. No se incluyen las filas duplicadas en el resultado, a menos que coloque la opción "all".

Se deben especificar los nombres de los campos en la primera instrucción "select".

Puede emplear la cláusula "order by".

Puede dividir una consulta compleja en varias consultas "select" y luego emplear el operador "union" para combinarlas.

Una academia de enseñanza almacena los datos de los alumnos en una tabla llamada "alumnos" y los datos de los profesores en otra denominada "profesores".
La academia necesita el nombre y domicilio de profesores y alumnos para enviarles una tarjeta de invitación.

Para obtener los datos necesarios de ambas tablas en una sola consulta necesitamos realizar una unión:

 select nombre, domicilio from alumnos
  union
 select nombre, domicilio from profesores;

El primer "select" devuelve el nombre y domicilio de todos los alumnos; el segundo, el nombre y domicilio de todos los profesores.

Los encabezados del resultado de una unión son los que se especifican en el primer "select".

Problema resuelto

Trabajamos con las tablas "alumnos" y "profesores".
Eliminamos ambas tablas si existen:

drop table if exists alumnos;
drop table if exists profesores;

Creamos las dos tablas:

create table alumnos(
  documento text primary key,
  nombre text,
  domicilio text
 );
 
 create table profesores(
  documento text primary key,
  nombre text,
  domicilio text
 );

Almacenamos algunos registros de prueba:

 insert into alumnos (documento,nombre,domicilio)
   values('30000000','Juan Perez','Colon 123');
 insert into alumnos (documento,nombre,domicilio)
  values('30111111','Marta Morales','Caseros 222');
 insert into alumnos (documento,nombre,domicilio)
  values('30222222','Laura Torres','San Martin 987');
 insert into alumnos (documento,nombre,domicilio)
  values('30333333','Mariano Juarez','Avellaneda 34');
 insert into alumnos (documento,nombre,domicilio)
  values('23333333','Federico Lopez','Colon 987');
 
 insert into profesores (documento,nombre,domicilio)
  values('22222222','Susana Molina','Sucre 345');
 insert into profesores (documento,nombre,domicilio)
  values('23333333','Federico Lopez','Colon 987'); 

La academia necesita el nombre y domicilio de profesores y alumnos para enviarles una tarjeta de invitación. Empleamos el operador "union" para obtener dicha información de ambas tablas:

 select nombre, domicilio from alumnos
  union
 select nombre, domicilio from profesores; 

Note que existe un profesor que también está presente en la tabla "alumnos"; dicho registro aparece una sola vez en el resultado de "union". Si queremos que las filas duplicadas aparezcan, debemos emplear "all":

 select nombre, domicilio from alumnos
  union all
 select nombre, domicilio from profesores; 

Ordenamos por domicilio:

 select nombre, domicilio from alumnos
  union
 select nombre, domicilio from profesores
  order by domicilio; 

Podemos agregar una columna extra a la consulta con el encabezado "condicion" en la que aparezca el literal "profesor" o "alumno" según si la persona es uno u otro:

 select nombre, domicilio, 'alumno' as condicion from alumnos
  union
 select nombre, domicilio,'profesor' from profesores
  order by condicion;  

Problema propuesto

Un supermercado almacena en una tabla denominada "proveedores" los datos de las compañías que le proveen de mercaderías; en una tabla llamada "clientes", los datos de los comercios que le compran y en otra tabla "empleados" los datos de los empleados.

  1. Borrar las tres tablas si ya existen.

  2. Crear las tablas con las siguientes estructuras:

     create table proveedores(
      codigo integer primary key,
      nombre text,
      domicilio text
     );
     create table clientes(
      codigo integer primary key,
      nombre text,
      domicilio text
     );
     create table empleados(
      documento text primary key,
      nombre text,
      apellido text,
      domicilio text
     );
    
  3. Almacenamos algunos datos de prueba:

     insert into proveedores(nombre,domicilio) values('Bebida cola','Colon 123');
     insert into proveedores(nombre,domicilio) values('Carnes Unica','Caseros 222');
     insert into proveedores(nombre,domicilio) values('Lacteos Blanca','San Martin 987');
     
     insert into clientes(nombre,domicilio) values('Supermercado Lopez','Avellaneda 34');
     insert into clientes(nombre,domicilio) values('Almacen Anita','Colon 987');
     insert into clientes(nombre,domicilio) values('Garcia Juan','Sucre 345');
     
     insert into empleados(documento,nombre,apellido,domicilio)
      values('23333333','Federico','Lopez','Colon 987');
     insert into empleados(documento,nombre,apellido,domicilio)
      values('28888888','Ana','Marquez','Sucre 333');
     insert into empleados(documento,nombre,apellido,domicilio)
      values('30111111','Luis','Perez','Caseros 956');
    
  4. El supermercado quiere enviar una tarjeta de salutación a todos los proveedores, clientes y empleados y necesita el nombre y domicilio de todos ellos. Emplee el operador "union" para obtener dicha información de las tres tablas.

  5. Agregue una columna con un literal para indicar si es un proveedor, un cliente o un empleado y ordene por dicha columna.

Solución
drop table if exists proveedores;
drop table if exists clientes;
drop table if exists empleados;

 create table proveedores(
  codigo integer primary key,
  nombre text,
  domicilio text
 );
 create table clientes(
  codigo integer primary key,
  nombre text,
  domicilio text
 );
 create table empleados(
  documento text primary key,
  nombre text,
  apellido text,
  domicilio text
 );

 insert into proveedores(nombre,domicilio) values('Bebida cola','Colon 123');
 insert into proveedores(nombre,domicilio) values('Carnes Unica','Caseros 222');
 insert into proveedores(nombre,domicilio) values('Lacteos Blanca','San Martin 987');
 
 insert into clientes(nombre,domicilio) values('Supermercado Lopez','Avellaneda 34');
 insert into clientes(nombre,domicilio) values('Almacen Anita','Colon 987');
 insert into clientes(nombre,domicilio) values('Garcia Juan','Sucre 345');
 
 insert into empleados(documento,nombre,apellido,domicilio)
  values('23333333','Federico','Lopez','Colon 987');
 insert into empleados(documento,nombre,apellido,domicilio)
  values('28888888','Ana','Marquez','Sucre 333');
 insert into empleados(documento,nombre,apellido,domicilio)
  values('30111111','Luis','Perez','Caseros 956');

 select nombre, domicilio from proveedores
  union
 select nombre, domicilio from clientes
  union
 select (apellido||' '||nombre), domicilio from empleados;  
 
 select nombre, domicilio, 'proveedor' as categoria from proveedores
  union
 select nombre, domicilio, 'cliente' from clientes
  union
 select (apellido||' '||nombre), domicilio , 'empleado' from empleados
  order by categoria; 

Ejecución de ejercicios online

Puede ejecutar comandos de SQLite directamente en el sitio sin tener que instalar nada en su computadora.

Resultado.....