八:子查詢(where、having)
阿新 • • 發佈:2021-07-26
#進階七:子查詢
/*
說明:當一個查詢語句中又嵌套了另一個完整的select語句,則被巢狀的select語句稱為子查詢或內查詢
外面的select語句稱為主查詢或外查詢。
分類:
按子查詢出現的位置進行分類:
1、select後面
要求:子查詢的結果為單行單列(標量子查詢)
2、from後面
要求:子查詢的結果可以為多行多列
3、where或having後面 ★
要求:子查詢的結果必須為單列
單行子查詢
多行子查詢
4、exists後面
要求:子查詢結果必須為單列(相關子查詢)
特點:
1、子查詢放在條件中,要求必須放在條件的右側
2、子查詢一般放在小括號中
3、子查詢的執行優先於主查詢
4、單行子查詢對應了 單行操作符:> < >= <= = <>
多行子查詢對應了 多行操作符:any/some all in
#一、放在where或having後面
#一)單行子查詢
#案例1:誰的工資比 Abel 高?
#①查詢Abel的工資
SELECT salary
FROM employees
WHERE last_name = 'Abel'
#②查詢salary>①的員工資訊
SELECT last_name,salary
FROM employees
WHERE salary>(
SELECT salary
FROM employees
WHERE last_name = 'Abel'
);
#案例2:返回job_id與141號員工相同,salary比143號員工多的員工姓名,job_id 和工資
#①查詢141號員工的job_id
SELECT job_id
FROM employees
WHERE employee_id = 141
#②查詢143號員工的salary
SELECT salary
FROM employees
WHERE employee_id = 143
③查詢job_id=① and salary>②的資訊
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 MIN(salary)
FROM employees
#②查詢salary=①的員工的last_name,job_id和salary
SELECT last_name,job_id,salary
FROM employees
WHERE salary=(
SELECT MIN(salary)
FROM employees
);
#案例4:查詢最低工資大於50號部門最低工資的部門id和其最低工資
#①查詢50號部門的最低工資
SELECT MIN(salary)
FROM employees
WHERE department_id = 50
#②查詢各部門的最低工資,篩選看哪個部門的最低工資>①
SELECT MIN(salary),department_id
FROM employees
GROUP BY department_id
HAVING MIN(salary)>(
SELECT MIN(salary)
FROM employees
WHERE department_id = 50
);
練習:
#1. 查詢和 Zlotkey 相同部門的員工姓名和工資
#①查詢Zlotkey的部門編號
SELECT department_id
FROM employees
WHERE last_name = 'Zlotkey'
#②查詢department_id = ①的員工姓名和工資
SELECT last_name,salary
FROM employees
WHERE department_id = (
SELECT department_id
FROM employees
WHERE last_name = 'Zlotkey'
);
#2. 查詢工資比公司平均工資高的員工的員工號,姓名和工資。
#①查詢平均工資
SELECT AVG(salary)
FROM employees
#②查詢salary>①的資訊
SELECT employee_id,last_name,salary
FROM employees
WHERE salary>(
SELECT AVG(salary)
FROM employees
);
#二)多行子查詢
/*
in:判斷某欄位是否在指定列表內
x in(10,30,50)
any / some:判斷某欄位的值是否滿足其中任意一個
x>any(10,30,50) 等價於 x>min()
x=any(10,30,50) 等價於 x in(10,30,50)
all:判斷某欄位的值是否滿足裡面所有的
x >all(10,30,50) 等價於 x >max()
*/
#案例1:返回location_id是1400或1700的部門中的所有員工姓名
#①查詢location_id是1400或1700的部門
SELECT department_id
FROM departments
WHERE location_id IN(1400,1700)
#②查詢department_id = ①的姓名
SELECT last_name 員工姓名
FROM employees
WHERE department_id IN(
SELECT DISTINCT department_id
FROM departments
WHERE location_id IN(1400,1700)
);
#題目:返回其它部門中比job_id為‘IT_PROG’部門任一工資低的員工的員工號、姓名、job_id 以及salary
#①查詢job_id為‘IT_PROG’部門的工資
SELECT DISTINCT salary
FROM employees
WHERE job_id = 'IT_PROG'
#②查詢其他部門的工資<任意一個①的結果
SELECT employee_id,last_name,job_id,salary
FROM employees
WHERE salary<ANY(
SELECT DISTINCT salary
FROM employees
WHERE job_id = 'IT_PROG'
);
等價於
SELECT employee_id,last_name,job_id,salary
FROM employees
WHERE salary<(
SELECT MAX(salary)
FROM employees
WHERE job_id = 'IT_PROG'
);
#案例3:返回其它部門中比job_id為‘IT_PROG’部門所有工資都低的員工 的員工號、姓名、job_id 以及salary
#①查詢job_id為‘IT_PROG’部門的工資
SELECT DISTINCT salary
FROM employees
WHERE job_id = 'IT_PROG'
#②查詢其他部門的工資<所有①的結果
SELECT employee_id,last_name,job_id,salary
FROM employees
WHERE salary<ALL(
SELECT DISTINCT salary
FROM employees
WHERE job_id = 'IT_PROG'
);
等價於
SELECT employee_id,last_name,job_id,salary
FROM employees
WHERE salary<(
SELECT MIN(salary)
FROM employees
WHERE job_id = 'IT_PROG'
);
#二、放在select後面
#案例;查詢部門編號是50的員工個數
#方式一;
SELECT COUNT(*)
FROM `employees`
WHERE `department_id`=50;
#方式二:
SELECT
(
SELECT COUNT(*)
FROM employees
WHERE department_id = 50
) 個數;
#三、放在from後面
#案例:查詢每個部門的平均工資的工資級別
#①查詢每個部門的平均工資
SELECT AVG(salary),department_id
FROM employees
GROUP BY department_id
#②將①和sal_grade兩表連線查詢
SELECT dep_ag.department_id,dep_ag.ag,g.grade
FROM sal_grade g
JOIN (
SELECT AVG(salary) ag,department_id
FROM employees
GROUP BY department_id
) dep_ag ON dep_ag.ag BETWEEN g.min_salary AND g.max_salary;
#四、放在exists後面
#案例1 :查詢有無名字叫“Abel”的員工資訊
SELECT EXISTS(
SELECT *
FROM employees
WHERE last_name = 'Abel'
) 有無Abel;
#案例2:查詢沒有女朋友的男神資訊
USE girls;
SELECT bo.*
FROM boys bo
WHERE bo.`id` NOT IN(
SELECT boyfriend_id
FROM beauty b
)
本文來自部落格園,作者:zhang-X,轉載請註明原文連結:https://www.cnblogs.com/YY-zhang/p/15060483.html