PS:本文所用数据表可参照前文: mysql基础复习——连接查询
子查询
出现在其他语句中的select语句称为子查询或者内查询 外部的查询语句成为主查询或外查询 分类: 子查询出现的位置 select后:仅支持标量子查询; from后:支持表子查询; where或having后:标量子查询(单行)、列子查询(多行)、行子查询; exists后:表子查询; 按结果集的行列数区分: 标量子查询(结果集只有一行一列); 列子查询(结果集有一列多行); 行子查询(结果集有一行多列); 表子查询(结果集一般为多行多列);
一、where或having后
1、标量子查询(结果集只有一行一列); 2、列子查询(结果集有一列多行); 3、行子查询(结果集有一行多列);
特点: ①子查询放在小括号内 ②子查询一般放在条件的右侧 ③标量子查询一般搭配多行操作符使用 ④列子查询,搭配多行操作符
标量子查询
SELECT
e
.last_name
, e
.salary
FROM
employees
AS e
WHERE
e
.`salary
`>(
SELECT
e
.`salary
`
FROM
employees
AS e
WHERE
e
.`last_name
` = 'Abel'
);
SELECT last_name
,job_id
,salary
FROM employees
WHERE job_id
= (
SELECT job_id
FROM employees
WHERE employee_id
= 141
)
AND
salary
> (
SELECT salary
FROM employees
WHERE employee_id
= 143
);
SELECT last_name
, job_id
, salary
FROM employees
WHERE salary
= (
SELECT MIN(salary
)
FROM employees
);
SELECT department_id
, MIN(salary
)
FROM employees
GROUP BY department_id
HAVING MIN(salary
) > (
SELECT MIN(salary
)
FROM employees
WHERE department_id
= 50
);
列子查询
select last_name
from employees
where department_id
in(
SELECT department_id
FROM departments
WHERE location_id
IN(1400,1700)
);
select employee_id
, last_name
,job_id
, salary
from employees
where salary
< any(
select distinct salary
from employees
where job_id
= 'IT_PROG'
)
and job_id
<> 'IT_PROG';
select employee_id
,last_name
,job_id
,salary
from employees
where salary
< all(
SELECT salary
FROM employees
WHERE job_id
= 'IT_PROG'
);
行子查询
SELECT *
FROM employees
WHERE employee_id
= (
SELECT MIN(employee_id
)
FROM employees
)
AND salary
= (
SELECT MAX(salary
)
FROM employees
);
SELECT *
FROM employees
WHERE (employee_id
, salary
) = (
SELECT MIN(employee_id
), MAX(salary
)
FROM employees
);
二、在select后的子查询
SELECT d
.*, (
SELECT COUNT(*)
FROM employees
AS e
WHERE d
.`department_id
`=e
.`department_id
`
) AS 'count'
FROM departments
AS d
;
SELECT d
.*,COUNT(e
.`employee_id
`) AS 'count'
FROM departments
AS d
LEFT OUTER JOIN employees
AS e
ON d
.`department_id
`=e
.`department_id
`
GROUP BY d
.`department_id
`
SELECT salarys
.*,grade_level
FROM (
SELECT e
.`department_id
`,AVG(salary
) AS avg_salary
FROM employees
AS e
GROUP BY e
.`department_id
`
) AS salarys
INNER JOIN job_grades
AS job
ON salarys
.`avg_salary
` BETWEEN job
.`lowest_sal
` AND job
.`highest_sal
`;
三、exists后
SELECT department_name
FROM departments d
WHERE EXISTS(
SELECT employee_id
FROM employees e
WHERE e
.`department_id
`=d
.`department_id
`
);
子查询案例
SELECT last_name
, salary
FROM employees
AS e
WHERE e
.`department_id
` = (
SELECT department_id
FROM employees
AS e2
WHERE e2
.`last_name
` = 'Zlotkey'
);
SELECT employee_id
, last_name
, salary
FROM employees
AS e
WHERE e
.`salary
`>(
SELECT AVG(salary
)
FROM employees
);
SELECT employee_id
, last_name
, salary
FROM employees
AS e
WHERE e
.`salary
` > (
SELECT AVG(salary
)
FROM employees
AS e2
GROUP BY e2
.`department_id
`
HAVING e
.`department_id
` = e2
.`department_id
`
);
SELECT employee_id
, last_name
, salary
FROM employees
AS e
inner join (
SELECT AVG(salary
) as avgsal
, department_id
FROM employees
AS e2
GROUP BY e2
.`department_id
`
) as avg_salary
on e
.`department_id
` = avg_salary
.department_id
where e
.`salary
` > avg_salary
.avgsal
;
SELECT employee_id
, last_name
FROM employees
AS e
WHERE e
.`department_id
` IN(
SELECT department_id
FROM employees
AS e2
WHERE e2
.`last_name
` LIKE '%u%'
);
SELECT employee_id
FROM employees
AS e
WHERE e
.`department_id
` IN(
SELECT department_id
FROM departments
AS d
WHERE d
.`location_id
` = 1700
);
select last_name
, salary
from employees
as e
where e
.`manager_id
` in (
select employee_id
from employees
as e2
where e2
.`last_name
`='K_ing'
);
SELECT CONCAT
(first_name
,'.',last_name
) AS '姓.名'
FROM employees
AS e
WHERE e
.`salary
` = (
SELECT MAX(salary
)
FROM employees
);
SELECT last_name
, salary
FROM employees
AS e
WHERE e
.`salary
` = (
SELECT MIN(salary
)
FROM employees
);
SELECT * FROM departments
AS d
WHERE d
.`department_id
`= (
SELECT department_id
FROM employees
AS e
GROUP BY e
.`department_id
`
HAVING AVG(e
.`salary
`)=(
SELECT MIN(d_avg
.d_avgs
)
FROM (
SELECT AVG(salary
) AS d_avgs
FROM employees
GROUP BY department_id
) AS d_avg
)
);
SELECT * FROM departments
AS d
WHERE d
.`department_id
` = (
SELECT department_id
FROM employees
AS e
GROUP BY e
.`department_id
`
ORDER BY AVG(salary
) ASC
LIMIT 1
);
SELECT d
.*,AVG(e
.`salary
`) AS 平均工资
FROM departments
AS d
INNER JOIN employees
AS e
ON d
.`department_id
` = e
.`department_id
`
GROUP BY d
.`department_id
`
HAVING d
.`department_id
`=(
SELECT department_id
FROM employees
AS e
GROUP BY e
.`department_id
`
ORDER BY AVG(salary
) ASC
LIMIT 1
);
SELECT * FROM jobs
WHERE jobs
.`job_id
`=(
SELECT job_id
FROM employees
AS e
GROUP BY e
.`job_id
`
ORDER BY AVG(salary
) DESC
LIMIT 1
);
SELECT department_id
,AVG(salary
)
FROM employees
AS e
GROUP BY department_id
HAVING AVG(salary
) > (
SELECT AVG(salary
)
FROM employees
)
SELECT *
FROM employees
AS e
WHERE e
.`employee_id
` IN(
SELECT DISTINCT manager_id
FROM employees
);
select min(salary
),e
.`department_id
`
from employees
as e
where e
.`department_id
` = (
SELECT e
.`department_id
`
FROM employees
AS e
GROUP BY e
.`department_id
`
ORDER BY MAX(salary
) ASC
LIMIT 1
)
group by e
.`employee_id
`
SELECT last_name
, department_id
, email
, salary
FROM employees
AS e
WHERE e
.`employee_id
` IN(
SELECT manager_id
FROM employees
AS e
WHERE e
.`department_id
`=(
SELECT e
.`department_id
`
FROM employees
AS e
GROUP BY e
.`department_id
`
ORDER BY MAX(salary
) DESC
LIMIT 1
)
);