MySQL子查詢的使用


出現在select語句中的select語句,稱之爲子查詢或內查詢。外部的select查詢語句,被稱爲主查詢或外查詢。子查詢按結果集的行列數不同分爲4種,標量子查詢、列子查詢、行子查詢、表子查詢。

標量子查詢 列子查詢 行子查詢 表子查詢
結果集 一行一列 一列多行 一行多列 一般爲多行多列
位置 select/where/having後 where/having後 where/having後 from/exists後面

子查詢的特點

1:子查詢放在小括號內。
2:子查詢一般放在條件的右側。
3:標量子查詢,一般搭配着單行單列操作符使用 >、<、>=、<=、=、<>、!=
4:列子查詢,一般搭配着多行操作符使用

in(not in):列表中的“任意一個”
any或者some:和子查詢返回的“某一個值”比較,比如a>some(10,20,30),a大於子查詢中任意一個即可,a大於子查詢中最小值即可,等同於a>min(10,20,30)。
all:和子查詢返回的“所有值”比較,比如a>all(10,20,30),a大於子查詢中所有值,換句話
說,a大於子查詢中最大值即可滿足查詢條件,等同於a>max(10,20,30);

5:子查詢的執行優先於主查詢執行,因爲主查詢的條件用到了子查詢的結果。


創建五張表,對下列表進行描述解釋

表名 描述
departments 部門表
employees 員工信息表
jobs 職位信息表
locations 位置表
job_grades 薪資等級表

select後面的子查詢

子查詢位於select後面的,僅僅支持標量子查詢。

示例:查詢每個部門員工個數

SELECT
 a.*,
	(SELECT count(*)
	 FROM employees b
	 WHERE b.department_id = a.department_id) AS 員工個數
FROM departments a;

from後面的子查詢

將子查詢的結果集充當一張表,要求必須起別名,否者這個表找不到。
然後將真實的表和子查詢結果表進行連接查詢。

示例:查詢每個部門平均工資的工資等級

-- 1:查詢每個部門的平均工資
SELECT department_id,avg(a.salary)
FROM employees a
GROUP BY a.department_id;

-- 2:查詢所有薪資等級
SELECT * FROM job_grades;

-- 3:將上面2個結果連接查詢,篩選條件:平均工資 between lowest_sal and highest_sal;
SELECT
 t1.department_id,
 sa AS '平均工資',
 t2.grade_level
FROM 
(SELECT department_id,avg(a.salary) sa FROM employees a
 GROUP BY a.department_id) t1, job_grades t2
WHERE
 t1.sa BETWEEN t2.lowest_sal AND t2.highest_sal;

查詢結果如下:
+---------------+--------------+-------------+
| department_id | 平均工資   | grade_level |
+---------------+--------------+-------------+
|      NULL |  7000.000000 | C      |
|       10 |  4400.000000 | B      |
|       20 |  9500.000000 | C      |
|       30 |  4150.000000 | B      |
|       40 |  6500.000000 | C      |
|       50 |  3475.555556 | B      |
|       60 |  5760.000000 | B      |
|       70 | 10000.000000 | D      |
|       80 |  8955.882353 | C      |
|       90 | 19333.333333 | E      |
|      100 |  8600.000000 | C      |
|      110 | 10150.000000 | D      |
+---------------+--------------+-------------+
12 rows in set (0.00 sec)

where和having後面的子查詢

where或having後面,可以使用下面三種
1:標量子查詢(單行單列行子查詢)
2:列子查詢(單列多行子查詢)
3:行子查詢(一行多列)

標量子查詢

標量子查詢是單行單列的子查詢,查詢結果只有一行一列。

示例1:查詢誰的工資比Abel的高

/*①查詢abel的工資【改查詢是標量子查詢】*/
SELECT salary
FROM employees
WHERE last_name = 'Abel';

/*②查詢員工信息,滿足salary>①的結果*/
SELECT *
FROM employees a
WHERE a.salary > (SELECT salary
         FROM employees
         WHERE last_name = 'Abel');

示例2:查詢最低工資大於50號部門最低工資的部門id和其最低工資【having】

**
/*①查詢50號部門的最低工資*/
SELECT min(salary)
FROM employees
WHERE department_id = 50;

/*②查詢每個部門的最低工資*/
SELECT
 min(salary),
 department_id
FROM employees
GROUP BY department_id;

/*③在②的基礎上篩選,滿足min(salary)>①*/
SELECT
 min(a.salary) minsalary,
 department_id
FROM employees a
GROUP BY a.department_id
HAVING min(a.salary) > (SELECT min(salary)
            FROM employees
            WHERE department_id = 50);**

列子查詢

列子查詢是單列多行子查詢,需要搭配多行操作符使用:in(not in)、any/some、all。
爲了提升效率,最好去重一下distinct關鍵字。

示例:返回location_id是1400或1700的部門中的所有員工姓名

/*①查詢location_id是1400或1700的部門編號*/
SELECT DISTINCT department_id
FROM departments
WHERE location_id IN (1400, 1700);

/*②查詢員工姓名,要求部門是①列表中的某一個*/
SELECT a.last_name
FROM employees a
WHERE a.department_id IN (SELECT DISTINCT department_id
             FROM departments
             WHERE location_id IN (1400, 1700));

行子查詢

子查詢結果集一行多列

示例:查詢員工編號最小並且工資最高的員工信息

SELECT *
FROM employees a
WHERE (a.employee_id, a.salary) = (SELECT
                  min(employee_id),
                  max(salary)
                 FROM employees);

exists後面的子查詢

1:語法:exists(完整的查詢語句)。
2: exists查詢結果:1或0,exists查詢的結果用來判斷子查詢的結果集中是否有值。
3:一般來說,能用exists的子查詢,絕對都能用in代替,所以exists用的少。
4: 和前面的查詢不同,這先執行主查詢,然後主查詢查詢的結果,再根據子查詢進行過濾,子查詢中涉及到主查詢中用到的字段,所以叫相關子查詢

簡單示例:

mysql> SELECT exists(SELECT employee_id
       FROM employees
       WHERE salary = 300000) AS 'exists返回1或者0';
+----------------------+
| exists返回1或者0   |
+----------------------+
|          			 0 |
+----------------------+
1 row in set (0.00 sec)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章