子查詢介紹:出現(xiàn)在其他語(yǔ)句中的select語(yǔ)句,被包裹的select語(yǔ)句就是子查詢或查詢
包裹子查詢的外部的查詢語(yǔ)句:稱主查詢語(yǔ)句
案例:查詢?cè)谖恢镁幪?hào)為1700的部門里的所有員工的名字
SELECT last_name FROM employees WHERE department_id
IN(SELECT department_id FROM departments
WHERE location_id=1700
);
1.子查詢分類
通過(guò)位置來(lái)分:
SELECT 后面:僅僅支持量子查詢
FROM 后面:支持表查詢
WHERE 或having 后面: 支持標(biāo)量子查詢(重要) 列子查詢(重要) 行子查詢(用的較少)
EXISTS 后面(相關(guān)查詢):支持表子查詢
按結(jié)果集的行列數(shù)不同的分類
標(biāo)量子查詢(結(jié)果集只有一行一列)
列子查詢(結(jié)果集只有一列但有多行)
行子查詢(結(jié)果集只有一行當(dāng)有多列)
表子查詢(結(jié)果集多行多列)
2.子查詢特點(diǎn)
子查詢放在小括號(hào)內(nèi)
子查詢一般放在條件但右側(cè)
標(biāo)量子查詢,一般搭配著單行操作符來(lái)使用(> < >= <= <> =)
列子查詢,一般搭配著多行操作符使用:in any/some all
子查詢但執(zhí)行順序優(yōu)先于主查詢(SELECT后的子查詢例外)
3.where后面的標(biāo)量子查詢
案例:查詢工資比Abel這個(gè)人的高的員工信息
SELECT * FROM employees
WHERE salary >(
SELECT salary
FROM employees
WHERE last_name = 'Abel'
);
案例:查詢job_id與141號(hào)員工相同,salary比143號(hào)員工多的員工姓名,job_id 和工資
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);
這個(gè)案例說(shuō)明一個(gè)主查詢里可以放很多個(gè)子查詢
案例:子查詢里用到分組查詢函數(shù):查詢員工工資最少的員工的last_name,job_id和salary
SELECT last_name,job_id,salary FROM employees
WHERE salary = (SELECT min(salary) FROM employees );
案例:查詢最低工資大于50號(hào)部門最低工資的部門id和其最低工資
SELECT department_id,MIN(salary)
FROM employees
GROUP BY department_id
HAVING MIN(salary)>(SELECT MIN(salary) FROM employees WHERE department_id =50 )
4.where后面的列子查詢(行多子查詢)
首先來(lái)看一下多行操作符:
in/not in:等于列表中的任意一個(gè)
a in(10,20,30); 可以替換 a=10 or a=20 or a=30
any/some:和子查詢返回的某一個(gè)比較
a > any(10,20,30); 可以替換 a > min(10,20,30)
all:和子查詢返回的所有值比較
a>all(10,20,30); 可以替換 a > max(10,20,30)
案例:返回location_id 是1400或1700的部門中的所有員工的名字
SELECT last_name FROM employees WHERE department_id
IN(SELECT department_id FROM departments WHERE location_id =1400 OR location_id=1700
);
案例:查詢其他工種中比job_id為'IT_PROG'的員工某一工資低的員工的員工號(hào),姓名,job_id和salary
SELECT employee_id ,last_name,job_id,salary
FROM employees
WHERE
job_id <>'IT_PROG' AND
salary < any(SELECT salary FROM employees WHERE job_id ='IT_PROG');
案例:查詢其他工種中比job_id為'IT_PROG'的員工所有工資低的員工的員工號(hào),姓名,job_id和salary
SELECT employee_id ,last_name,job_id,salary
FROM employees
WHERE
job_id <>'IT_PROG' AND
salary < ALL(SELECT salary FROM employees WHERE job_id ='IT_PROG');
5.where后面的執(zhí)行子查詢(一行多列)
案例:查詢員工編號(hào)最小且工資最高的員工信息
SELECT *FROM employees
WHERE
employee_id = (SELECT MIN(employee_id) FROM employees)
and
salary =(SELECT MAX(salary) FROM employees);
執(zhí)行子查詢
SELECT *FROM employees
WHERE (employee_id,salary)=(SELECT min(employee_id),max(salary)FROM employees);
6.SELECT 和FROM 后面的子查詢
SELECT 后面(很少用到的,可以用前面講的方法實(shí)現(xiàn)):
案例:查詢每個(gè)部門的部門信息和對(duì)應(yīng)的員工個(gè)數(shù)(不用連接查詢)
SELECT d.*,COUNT(e.employee_id) FROM departments d
LEFT JOIN employees e
ON d.department_id = e.department_id
GROUP BY d.department_id;
SELECT d.*,( SELECT COUNT(*) FROM employees e WHERE d.department_id =e.department_id )FROM departments d;
案例:查詢員工號(hào)等于102的部門名(不用連接查詢)
SELECT department_name FROM departments WHERE department_id =(SELECT e.department_id FROM employees e WHERE e.employee_id=102);
SELECT (SELECT d.department_name FROM departments d WHERE d.department_id = e.department_id ) FROM employees e WHERE e.employee_id=102;
案例:查詢每個(gè)部門的平均工資等級(jí)
SELECT AVG(e.salary) FROM employees e GROUP BY e.department_id
(SELECT AVG(e.salary) avg_sal FROM employees e GROUP BY e.department_id) avg_sal_res 當(dāng)成一個(gè)新的表
SELECT avg_sal_res.avg_sal,g.grade_level
FROM
(SELECT AVG(e.salary) avg_sal FROM employees e GROUP BY e.department_id) avg_sal_res
INNER JOIN job_grades g
on avg_sal BETWEEN g.lowest_sal AND g.highest_sal;
6.EXISTS后面(相關(guān)子查詢)
exists的作用是:判斷子查詢有沒(méi)有結(jié)果的存在
案例:
SELECT EXISTS(SELECT employee_id FROM employees);
SELECT EXISTS(SELECT employee_id FROM employees WHERE employee_id=99999);
案例:查詢有員工的部門名,EXISTS 很少使用
SELECT EXISTS(SELECT employee_id FROM employees WHERE employee_id=99999);
SELECT department_name FROM departments d WHERE EXISTS(SELECT * FROM employees e WHERE e.department_id = d.department_id);
SELECT department_name FROM departments d WHERE department_id IN(SELECT e.department_id FROM employees e WHERE e.department_id = d.department_id);
注意
本文用到的myemployees.sql 文件在MySQL實(shí)戰(zhàn)2 語(yǔ)法、篩選條件和函數(shù) 附件中