# 進階7:子查詢
/*
含義:
出現在其他語句中的select語句,稱爲子查詢或內查詢
外部的查詢語句,稱爲主查詢或外查詢
示例:
select frist_name from employees where
department_id in(
select department_id from departments
where location+id=17000
)
分類
按子查詢出現的位置:
select 後面(只能放標量子查詢)
from 後面(只支持表子查詢)
where或having 後面(標量子查詢、列子查詢、行子查詢)
exists 後面(又叫相關子查詢)(表子查詢)
按結果集的行列數不同:
標量子查詢(結果類只有一列或一行)
列子查詢(結果集只有一列多行)
行子查詢(結果集可以有一行多列)
表子查詢(結果集,一般爲多行多列)
*/
# 一、where或having後面
# 1.標量子查詢(單行子查詢)
# 2.列子查詢(多行子查詢)
# 3.行子查詢(多行多列)
/*
特點:
①子查詢放在小括號內
②子查詢一般放在條件的右側
③標量子查詢,一般搭配着單行操作符使用
> < >= <= = <>
列子查詢,一般搭配着多行操作符使用
IN、ANY/SOME、ALL
④子查詢的執行優先於主查詢的執行,主查詢的條件用到了子查詢的結果
*/
# 1.標量子查詢
# 案例1: 睡得工資比Abel高?
SELECT *
FROM employees
WHERE salary>
(
SELECT salary
FROM employees
WHERE last_name='Abel'
);
# 案例2:返回job_id與141號員工相同的,salary比143號員工多的員工 姓名,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
);
# 案例3:返回公司工資最少的員工的last_name,job_id\salary
SELECT last_name,job_id,salary
FROM employees
WHERE salary=(
SELECT MIN(salary)
FROM employees
);
# 案例4:查詢最低工資大於50號部門最低工資的部門id和其最低工資
SELECT employee_id,MIN(salary)
FROM employees
GROUP BY department_id
HAVING MIN(salary)>(
SELECT MIN(salary)
FROM employees
WHERE department_id=50
)
# 2.列子查詢
/*
返回多行
使用多行比較操作符
操作符 含義
IN/NOT IN 等於列表中的任意一個
ANY/SOME 和子查詢返回的某一個值比較
ALL 和子查詢返回的所有值比較
*/
# 案例1: 返回location_id是1400或1700的部門中的所有員工姓名
SELECT last_name
FROM employees
WHERE department_id IN(
SELECT DISTINCT department_id
FROM departments
WHERE location_id IN(1400,1700)
);
# 案例2: 返回其他工種中比job_id爲'IT_PROG'工種任一員工的員工號、姓名、job_id以及salary
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<(
SELECT DISTINCT MAX(salary)
FROM employees
WHERE job_id='IT_PROG'
) AND job_id <>'IT_PROG';
# 案例3: 返回其他工種中比job_id爲'IT_PROG'工種所有員工的員工號、姓名、job_id以及salary
SELECT employee_id,last_name,job_id,salary
FROM employees
WHERE salary<ALL(
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<(
SELECT DISTINCT MIN(salary)
FROM employees
WHERE job_id='IT_PROG'
) AND job_id <>'IT_PROG';
# 3.行子查詢(結果集一行多列或多行多列)
# 案例:查詢員工編號最小並且工資最高的員工信息
# 以前的方法
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 e.department_id=d.`department_id`
)
FROM departments AS d;
# 案例2: 查詢員工號=102的部門名
SELECT (
SELECT department_name
FROM departments AS d
INNER JOIN employees AS e
ON d.department_id=e.department_id
WHERE e.employee_id=102
) AS 部門;
# 三、from後面
/*
將子查詢結果做成一張表,要求該表必須要取別名
*/
# 案例:查詢每個部門的平均工資的工資等級
SELECT ag_dep.*,g.`grade_level`
FROM(
SELECT AVG(salary) AS ag,department_id
FROM employees
GROUP BY department_id
) AS ag_dep
INNER JOIN job_grades AS g
ON ag_dep.ag BETWEEN lowest_sal AND highest_sal;
# 四、exists後面(相關子查詢)
/*
語法:
exists(完整的查詢語句)
結果:
1或0
*/
# 案例1:查詢有員工的部門名
SELECT department_name
FROM departments AS d
WHERE EXISTS(
SELECT *
FROM employees AS e
WHERE d.`department_id`=e.`department_id`
);
# 案例2:查詢沒有女朋友的男生信息
SELECT bo.*
FROM boys AS bo
WHERE bo.id NOT IN(
SELECT boyfriend_id
FROM beauty
)
SELECT bo.*
FROM boys AS bo
WHERE NOT EXISTS(
SELECT boyfriend_id
FROM beauty AS b
WHERE bo.id=b.boyfriend_id
)
MySQL進階7:子查詢
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.