subconsulta postgresql

Introducción a las subconsultas

La subconsulta se refiere a una
declaración de consulta anidada en otras declaraciones SELECT, INSERT, UPDATE y DELETE
. La función de una subconsulta es algo similar a una consulta de unión de varias tablas y también se utiliza para devolver o filtrar datos de varias tablas relacionadas. Por
ejemplo, queremos saber qué empleados tienen un salario mensual mayor que el salario mensual promedio, lo cual se puede lograr mediante una subconsulta.

select e.first_name, e.last_name, e.salary
 from employees e
where salary > (select avg(salary) from employees);

Insertar descripción de la imagen aquí
La subconsulta debe colocarse entre paréntesis, también denominada consulta interna, y la declaración de consulta que contiene la subconsulta se denomina consulta externa. Además de la
cláusula WHERE, las subconsultas también se pueden utilizar en otras cláusulas, como listas SELECT, cláusulas FROM, etc.

tabla derivada

La subconsulta en la cláusula FROM se denomina tabla derivada (tabla derivada)

SELECT column1, column2, ...
 FROM (subquery) AS table_alias;

La subconsulta equivale a crear una tabla temporal alias_tabla

-- 获取每个部门的总月薪
select d.department_name,
 ds.sum_salary
 from departments d
 join (select department_id,
 sum(salary) as sum_salary
 from employees
 group by department_id) ds
 on (d.department_id = ds.department_id);

La subconsulta devuelve el número de departamento y el salario mensual total del departamento, luego se realiza la consulta de conexión con la tabla de departamentos.

operador EN

Si la subconsulta WHERE devuelve varios registros, puede utilizar el operador IN para el filtrado condicional:

-- in 
-- 存在 2008 年 01 月 01 日以后入职员工的部门
select *
from cps.public.departments d 
where d.department_id in 
(
select distinct e.department_id 
from cps.public.employees e 
where e.hire_date >= date '2008-01-01'
);

Insertar descripción de la imagen aquí

TODO operador

El operador TODO se utiliza con operadores de comparación para comparar un valor con la lista devuelta por una subconsulta:

-- all
-- 返回了月薪比销售部门(department_id = 80)所有员工都高的员工
select e.first_name ,
e.salary 
from cps.public.employees e 
where e.salary > all
(select e2.salary from cps.public.employees e2 where e2.department_id= 80);

El sql anterior es equivalente al siguiente sql

-- all
-- 返回了月薪比销售部门(department_id = 80)所有员工都高的员工
select e.first_name ,
e.salary 
from cps.public.employees e 
where e.salary > 
(select max(e2.salary)  from cps.public.employees e2 where e2.department_id= 80);

Insertar descripción de la imagen aquí

CUALQUIER operador

El operador ANY es similar al operador ALL, pero tiene efectos diferentes:

-- any
-- 返回了月薪比销售部门(department_id = 80)任何一个员工都高的员工
select e.first_name ,
e.salary 
from cps.public.employees e 
where e.salary > 
(select min(e2.salary)  from cps.public.employees e2 where e2.department_id= 80);

El sql anterior es equivalente al siguiente sql

-- any
-- 返回了月薪比销售部门(department_id = 80)任何一个员工都高的员工
select e.first_name ,
e.salary 
from cps.public.employees e 
where e.salary > any
(select e2.salary  from cps.public.employees e2 where e2.department_id= 80);

Insertar descripción de la imagen aquí
Además, ALGUNOS y CUALQUIER son sinónimos. El efecto de algunos es el mismo que cualquier

Subconsulta correlacionada

Existe otro tipo de subconsulta que hace referencia a columnas de la consulta externa y, por tanto, está relacionada con la consulta externa: se denominan subconsultas correlacionadas.

/*
 * 子查询中使用了外查询的字段(e.department_id)。对于外部查询中的每个员工,
 * 运行子查询返回他/她所在部门的平均月薪,然后传递给外部查询进行判断
 * */
-- 返回月薪大于所在部门平均月薪的员工
select 
e.first_name,
e.salary 
from cps.public.employees e 
where e.salary >
(select avg(e2.salary) from cps.public.employees e2 where e2.department_id  = e.department_id);

Insertar descripción de la imagen aquí
Las subconsultas correlacionadas se ejecutan una vez para cada fila de la consulta externa (la base de datos puede optimizar esto), mientras que las
subconsultas no correlacionadas se ejecutan solo una vez para toda la ejecución de la consulta.

subconsulta horizontal

En términos generales, las subconsultas solo pueden hacer referencia a campos en la consulta externa y no pueden usar campos en otras tablas en la misma jerarquía. Por ejemplo:

/**/
select 
d.department_name ,t.sum_sal
from cps.public.departments d 
join (
select sum(e.salary) sum_sal from cps.public.employees e where e.department_id = d.department_id 
) t on true;

Insertar descripción de la imagen aquí
La declaración anterior se refiere a los campos de la tabla de departamentos a la izquierda en JOIN, lo que genera un error de sintaxis. Para hacer esto, necesitamos
usar una subconsulta LATERAL. Al agregar la palabra clave LATERAL, la subconsulta puede hacer referencia
a columnas en la tabla de la izquierda:

/*
 * 每个部门的名称和总月薪
 * */
select 
d.department_name ,t.sum_sal
from cps.public.departments d 
cross join lateral (
select sum(e.salary) sum_sal from cps.public.employees e where e.department_id = d.department_id 
) t;

Insertar descripción de la imagen aquí

operador EXISTE

El operador EXISTS se utiliza para comprobar la existencia de resultados de subconsulta. EXISTS devuelve Verdadero si la subconsulta devuelve algún resultado;
en caso contrario, Falso

-- EXISTS
select * 
from cps.public.departments d 
where exists 
(select 1 from cps.public.employees e
where e.department_id = d.department_id 
and e.hire_date > date '2008-01-01'
);

Insertar descripción de la imagen aquí

-- not exists不存在
select * 
from cps.public.departments d 
where not exists 
(select 1 from cps.public.employees e
where e.department_id = d.department_id 
and e.hire_date > date '2008-01-01'
);

Insertar descripción de la imagen aquí

[NOT] IN se usa para verificar si un valor pertenece a la lista de resultados de una subconsulta (=). [NOT] EXISTS solo verifica la existencia del resultado de la subconsulta . NOT EXISTS se evalúa como Verdadero si NULL está presente en el resultado de la subconsulta; sin embargo, NOT IN se evalúa
como Falso porque el resultado de NOT (X = NULL) es NULL

-- in 在什么取值范围内
select *
from cps.public.departments d 
where d.department_id  in 
(select distinct e.department_id  from cps.public.employees e)

Insertar descripción de la imagen aquí

-- not in 不属于子查询结果列
select *
from cps.public.departments d 
where d.department_id not in 
(select distinct e.department_id  from cps.public.employees e)

Insertar descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/Java_Fly1/article/details/132702117
Recomendado
Clasificación