En este artículo veremos cómo utilizar subconsultas en PostgreSQL. Una subconsulta es realmente una consulta dentro de otra que te permite realizar consultas complejas.
Sintaxis
No hay una sintaxis única ya que puedes realizar la subconsulta tal y como la necesites, pero un ejemplo sencillo es el siguiente:
SELECT tabla1.columna1, tabla1.columnaN
FROM nombreTabla1 tabla1
WHERE tabla1.columna1 = ( SELECT tabla2.columna1
FROM nombreTabla2);
En el ejemplo anterior el orden de procesamiento es el siguiente:
- Primero se ejecuta la subconsulta.
- En segundo lugar obtiene los resultados de la segunda consulta.
- En tercer lugar ejecuta la primera consulta y devuelve los resultado cuando la condición se cumple.
Si utilizas subconsultas con el operador = debes asegurarte que la subconsulta solo te devolverá un único valor, de lo contrario fallará. Si necesitas que la subconsulta devuelva más de un valor utiliza el operador IN.
Ejemplo usando >
En el siguiente ejemplo realizamos una subconsulta que nos devuelve la media de los sueldos de los empleados y luego mostramos los empleados que su sueldo es superior a la media.
select *
from empleados
where sueldo > (select avg(sueldo)
from empleados);
Si ejecutamos la consulta comprobamos los resultados:
Ejemplo usando IN
En el siguiente ejemplo realizamos una subconsulta que nos devuelve los nombres de los empleados donde su sueldo es menor de 80000 y pertenecen al departamento de Inteligencia de negocio. (para obtener esta información lo podríamos realizar en una sola consulta, es solo un ejemplo de utilización del operador IN junto a la subconsulta)
select *
from empleados
where nombre IN (select e.nombre
from empleados e inner join departamentos d
on e.id_departamento = d.id_departamento
where sueldo < 80000
and d.nombre = 'Inteligencia de negocio');
Ejemplo completo
Copia y pega el siguiente código en tu consola de PostgreSQL y realiza paso a paso leyendo los comentarios.
--MiguelTroyano.com
-- Borramos las tablas si existen
drop table if exists empleados;
drop table if exists departamentos;
-- Creamos las tablas
create table empleados
(
id_empleado numeric(2,0) primary key,
id_departamento numeric(2,0),
nombre character varying(50),
puesto character varying(50),
fecha_alta date,
sueldo integer
);
create table departamentos
(
id_departamento numeric(2,0) primary key,
nombre character varying(50),
edificio character varying(50),
planta numeric(2,0)
);
-- Insertamos valores
insert into empleados
values (1,2,'Miguel Troyano','Analista',TO_DATE( '26/09/1986', 'DD/MM/YYYY'),60000),
(2,2,'Ismael Troyano','Analista',TO_DATE( '01/01/2001', 'DD/MM/YYYY'),60000),
(3,3,'Jose Troyano','Alta Dirección',TO_DATE( '01/01/2001', 'DD/MM/YYYY'),80000),
(4,5,'Pilar Redondo','Alta Dirección',TO_DATE( '02/02/2002', 'DD/MM/YYYY'),80000);
insert into departamentos
values (1,'Mantenimiento','Edificio 1',7),
(2,'Inteligencia de negocio','Edificio 2',7),
(3,'Recursos Humanos','Edificio 3',8),
(4,'Finanzas','Edificio 3',8);
-- Mostramos la información de la tabla de empleados
-- cuando el sueldo sea mayor a la media de todos los
-- empleados
select *
from empleados
where sueldo > (select avg(sueldo)
from empleados);
-- Mostramos la información de la tabla de empleados
-- cuando el nombre de los empleados cumpla con las condiciones
-- de la subconsulta
select *
from empleados
where nombre IN (select e.nombre
from empleados e inner join departamentos d
on e.id_departamento = d.id_departamento
where sueldo < 80000
and d.nombre = 'Inteligencia de negocio');