SQL SELECT(複雜查詢)之 自連線 & 子查詢 解析
SQL SELECT(複雜查詢)之 自連線 & 子查詢 解析 |
---|
一、自連線
概念:把一張表 當做多個表使用
語法:
select ...
from 表 a(別名)
join 表 b(別名)
on a.欄位=b.欄位
注意:
自連線也可以是 內連線也可以是外連線
自己與一張與自己完全一樣的從表建立關係 進行連線查詢
以下舉例所用表
employees表:欄位如下
employee_id, first_name, last_name, email, phone_number
job_id, salary, commission_pct, manage_id, department_id
案例: xx員工 為 xx上司 工作
分析:
employees表:欄位如下
employee_id, first_name, last_name, email, phone_number
job_id, salary, commission_pct, manage_id, department_id
manage_id 是員工id為emplo_id的領導者id 其對應的一條記錄也是
employees表中的一條普通員工記錄
/* 進一步分析: 1.相當於查詢員工名和上司名 2.將自己(employees表)當做兩個表, m和e */ #分析1 //相當於從employee表中查詢 經過匹配後 得到這個員工的領導 manager_id 再把它從這個表中查出來 SELECT e.`first_name` 員工名,m.`first_name` 老闆名 FROM employees e JOIN employees m ON e.`manager_id`=m.`employee_id` #分析2 通過自己與自己內連線 跟自連線 一樣 SELECT CONCAT(e.`first_name`,' work for ',m.`first_name`) info FROM employees e JOIN employees m ON e.`manager_id`=m.`employee_id`
二、子查詢
(一)子查詢
分類:
單行子查詢: 子查詢的結果集是一行
多行子查詢: 子查詢的結果集是多行
注意事項:
子查詢要包含在括號內。
將子查詢放在比較條件的右側。
單行操作符對應單行子查詢,多行操作符對應多行子查詢。
單行操作符:
> < >= <= = <>
多行操作符:
in(重點)、any(任意一個)、all(所有的)
not in
1、單行子查詢
比較的物件是唯一的一個而不是一個範圍集合
1.案例:誰的工資比 Abel 高?
/* 分析1: 求出Abel的工資 分析2: 篩選employees表,判斷 salary > Abel的工資 */ 求出Abel的工資,得到一個值 SELECT salary FROM employees WHERE last_name = 'Abel'; 篩選employees表,判斷 salary > Abel的工資 SELECT * FROM employees WHERE salary>11000; 結合以上兩部分析將第一個分析所得結果作為被比較的條件物件 SELECT * FROM employees WHERE salary>( SELECT salary FROM employees WHERE last_name = 'Abel' );
2.案例:返回job_id與141號員工相同,salary比143號員工多的員工
姓名,job_id 和工資
/*
分析1:先查詢 141 號員工的job_id
以及 143號員工的salary
*/
1》先查詢 141 號員工的job_id
以及 143號員工的salary
SELECT job_id
FROM employees
WHERE employee_id = 141
SELECT salary
FROM employees
WHERE employee_id = 143
2》結合以上兩部將其作為被比較的條件物件篩選指定的員工
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 子查詢中使用了組函式。
以下舉例所用表
employees表:欄位如下
employee_id, first_name, last_name, email, phone_number
job_id, salary, commission_pct, manage_id, department_id
案例 返回工資最少的員工的last_name,job_id和salary
SELECT last_name,job_id,salary
FROM employees
WHERE salary=(
//把如下語句獲取的值作為salary比較的條件物件
SELECT MIN(salary) FROM employees
);
SELECT * FROM employees;//檢視結果有沒有改變
4 子查詢中用到了having
案例:查詢最低工資大於50號部門最低工資的部門id和其最低工資
/*
分析1:先查詢50號部門的最低工資
分析2:每個部門的部門id和其最低工資
分析3:篩選看哪個部門的最低工資大於分析1的結果
*/
#分析1
SELECT MIN(salary)
FROM employees
WHERE department_id=50
#分析2
SELECT MIN(salary) ,department_id
FROM employees
GROUP BY department_id
#分析3
SELECT MIN(salary) ,department_id
FROM employees
GROUP BY department_id
HAVING MIN(salary)>(
SELECT MIN(salary)
FROM employees
WHERE department_id=50
);
非法使用單行子查詢,其實就是 子查詢結果集中返回的是多行
SELECT MIN(salary) ,department_id
FROM employees
GROUP BY department_id
HAVING MIN(salary)>(
SELECT salary
FROM employees
WHERE department_id>50//返回的是多個值物件
);
單行子查詢的結果集中出現 null的問題
SELECT MIN(salary) ,department_id
FROM employees
GROUP BY department_id
HAVING MIN(salary)>(
SELECT salary
FROM employees
WHERE department_id>300 //結果為null
);
單行子查詢的結果集多列的問題
SELECT MIN(salary) ,department_id
FROM employees
GROUP BY department_id
HAVING MIN(salary)>( //到這一步 用於比較的MIN(salary)有很多個 不
SELECT MIN(salary),department_id
FROM employees
WHERE department_id=50 //50號部門最低工資
);
二、多行子查詢
1.題目:
返回其它部門中比job_id為‘IT_PROG’部門任一工資低的員工的員
工號、姓名、job_id 以及salary
提示:比最高工資低 就行
/*
分析1: 先查詢 job_id為‘IT_PROG’部門任一工資
分析2: 查詢員工號、姓名、job_id 以及salary 比分析1的 結果中任意一個都低的
*/
1》. 先查詢 job_id為‘IT_PROG’部門任一工資
SELECT salary
FROM employees
WHERE job_id = 'IT_PROG'
2 》查詢員工號、姓名、job_id 以及salary 比分析1的 結果中任意一個都低的
SELECT employee_id,last_name,job_id,salary
FROM employees
WHERE salary<ANY(
SELECT salary
FROM employees
WHERE job_id = 'IT_PROG'
)
2.題目:返回其它部門中比job_id為‘IT_PROG’部門所有工資都低的員工
的員工號、姓名、job_id 以及salary
提示:相當於比 最小的工資還要低
SELECT employee_id,last_name,job_id,salary
FROM employees
WHERE salary<ALL(
SELECT salary
FROM employees
WHERE job_id = 'IT_PROG'
)
3.題目:返回其它部門中工資和 job_id為‘IT_PROG’部門的隨便一個工資 相同 的員工
SELECT employee_id,last_name,job_id,salary
FROM employees
WHERE salary NOT IN(
SELECT salary
FROM employees
WHERE job_id = 'IT_PROG'
)
語法:
in(值1,值2,值3)
salary =值1 or salary=值2 or salary=值3