MySQL多表查詢講解

1. 開始之前

-- ----------------------------
-- Table structure for dept
-- ----------------------------
DROP TABLE IF EXISTS `dept`;
CREATE TABLE `dept` (
  `did` int(11) NOT NULL AUTO_INCREMENT COMMENT '部門ID',
  `dname` varchar(60) DEFAULT NULL COMMENT '部門名稱',
  PRIMARY KEY (`did`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of dept
-- ----------------------------
BEGIN;
INSERT INTO `dept` VALUES (1, '研發部');
INSERT INTO `dept` VALUES (2, '人事部');
INSERT INTO `dept` VALUES (3, '測試部');
INSERT INTO `dept` VALUES (4, '銷售部');
INSERT INTO `dept` VALUES (5, '生產部');
COMMIT;

-- ----------------------------
-- Table structure for employee
-- ----------------------------
DROP TABLE IF EXISTS `employee`;
CREATE TABLE `employee` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主鍵',
  `name` varchar(60) NOT NULL COMMENT '姓名',
  `age` tinyint(4) DEFAULT NULL COMMENT '年齡',
  `sex` tinyint(2) NOT NULL DEFAULT '1' COMMENT '性別,1男,2女',
  `salary` decimal(10,2) NOT NULL COMMENT '薪資',
  `hire_date` date NOT NULL COMMENT '聘用日期',
  `dept_id` int(11) DEFAULT NULL COMMENT '部門ID',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of employee
-- ----------------------------
BEGIN;
INSERT INTO `employee` VALUES (1, '菜虛鯤', 20, 2, 10000.00, '2020-01-10', 1);
INSERT INTO `employee` VALUES (2, '奧力給', 30, 1, 18000.00, '2020-01-08', 1);
INSERT INTO `employee` VALUES (3, '老八', 28, 1, 7000.00, '2020-01-07', 1);
INSERT INTO `employee` VALUES (4, '小張', 25, 1, 8000.00, '2020-01-10', 1);
INSERT INTO `employee` VALUES (5, '小紅', 20, 2, 6000.00, '2020-01-05', 2);
INSERT INTO `employee` VALUES (6, '小麗', 23, 2, 6500.00, '2020-01-05', 2);
INSERT INTO `employee` VALUES (7, '小花', 21, 2, 5500.00, '2020-01-10', 2);
INSERT INTO `employee` VALUES (8, '馬小跳', 25, 1, 7000.00, '2020-01-01', 3);
INSERT INTO `employee` VALUES (9, '張大騷', 30, 1, 9000.00, '2020-01-07', 3);
INSERT INTO `employee` VALUES (10, '馬冬梅', 31, 2, 5000.00, '2020-01-07', 4);
INSERT INTO `employee` VALUES (11, '川堅果', 60, 1, 100.00, '2020-01-08', NULL);
COMMIT;

2. 多表聯合查詢

2.1 語法

select 字段1,字段2... from1,表2... [where 條件]

2.2 實戰

注意:多表聯合查詢需要添加條件,否則會直接輸出 左表*右表,這種結果稱之爲笛卡爾乘積
在這裏插入圖片描述
集合A中的數據乘以集合B中的數據等於笛卡爾乘積。

mysql> select * from employee,dept;
+----+-----------+-----+-----+----------+------------+---------+-----+-----------+
| id | name      | age | sex | salary   | hire_date  | dept_id | did | dname     |
+----+-----------+-----+-----+----------+------------+---------+-----+-----------+
|  1 | 菜虛鯤 |  20 |   2 | 10000.00 | 2020-01-10 |       1 |   1 | 研發部 |
|  1 | 菜虛鯤 |  20 |   2 | 10000.00 | 2020-01-10 |       1 |   2 | 人事部 |
|  1 | 菜虛鯤 |  20 |   2 | 10000.00 | 2020-01-10 |       1 |   3 | 測試部 |
|  1 | 菜虛鯤 |  20 |   2 | 10000.00 | 2020-01-10 |       1 |   4 | 銷售部 |
|  1 | 菜虛鯤 |  20 |   2 | 10000.00 | 2020-01-10 |       1 |   5 | 生產部 |
|  2 | 奧力給 |  30 |   1 | 18000.00 | 2020-01-08 |       1 |   1 | 研發部 |
|  2 | 奧力給 |  30 |   1 | 18000.00 | 2020-01-08 |       1 |   2 | 人事部 |
|  2 | 奧力給 |  30 |   1 | 18000.00 | 2020-01-08 |       1 |   3 | 測試部 |
|  2 | 奧力給 |  30 |   1 | 18000.00 | 2020-01-08 |       1 |   4 | 銷售部 |
|  2 | 奧力給 |  30 |   1 | 18000.00 | 2020-01-08 |       1 |   5 | 生產部 |
|  3 | 老八    |  28 |   1 | 7000.00  | 2020-01-07 |       1 |   1 | 研發部 |
|  3 | 老八    |  28 |   1 | 7000.00  | 2020-01-07 |       1 |   2 | 人事部 |
|  3 | 老八    |  28 |   1 | 7000.00  | 2020-01-07 |       1 |   3 | 測試部 |
|  3 | 老八    |  28 |   1 | 7000.00  | 2020-01-07 |       1 |   4 | 銷售部 |
|  3 | 老八    |  28 |   1 | 7000.00  | 2020-01-07 |       1 |   5 | 生產部 |
|  4 | 小張    |  25 |   1 | 8000.00  | 2020-01-10 |       1 |   1 | 研發部 |
|  4 | 小張    |  25 |   1 | 8000.00  | 2020-01-10 |       1 |   2 | 人事部 |
|  4 | 小張    |  25 |   1 | 8000.00  | 2020-01-10 |       1 |   3 | 測試部 |
|  4 | 小張    |  25 |   1 | 8000.00  | 2020-01-10 |       1 |   4 | 銷售部 |
|  4 | 小張    |  25 |   1 | 8000.00  | 2020-01-10 |       1 |   5 | 生產部 |
|  5 | 小紅    |  20 |   2 | 6000.00  | 2020-01-05 |       2 |   1 | 研發部 |
|  5 | 小紅    |  20 |   2 | 6000.00  | 2020-01-05 |       2 |   2 | 人事部 |
|  5 | 小紅    |  20 |   2 | 6000.00  | 2020-01-05 |       2 |   3 | 測試部 |
|  5 | 小紅    |  20 |   2 | 6000.00  | 2020-01-05 |       2 |   4 | 銷售部 |
|  5 | 小紅    |  20 |   2 | 6000.00  | 2020-01-05 |       2 |   5 | 生產部 |
|  6 | 小麗    |  23 |   2 | 6500.00  | 2020-01-05 |       2 |   1 | 研發部 |
|  6 | 小麗    |  23 |   2 | 6500.00  | 2020-01-05 |       2 |   2 | 人事部 |
|  6 | 小麗    |  23 |   2 | 6500.00  | 2020-01-05 |       2 |   3 | 測試部 |
|  6 | 小麗    |  23 |   2 | 6500.00  | 2020-01-05 |       2 |   4 | 銷售部 |
|  6 | 小麗    |  23 |   2 | 6500.00  | 2020-01-05 |       2 |   5 | 生產部 |
|  7 | 小花    |  21 |   2 | 5500.00  | 2020-01-10 |       2 |   1 | 研發部 |
|  7 | 小花    |  21 |   2 | 5500.00  | 2020-01-10 |       2 |   2 | 人事部 |
|  7 | 小花    |  21 |   2 | 5500.00  | 2020-01-10 |       2 |   3 | 測試部 |
|  7 | 小花    |  21 |   2 | 5500.00  | 2020-01-10 |       2 |   4 | 銷售部 |
|  7 | 小花    |  21 |   2 | 5500.00  | 2020-01-10 |       2 |   5 | 生產部 |
|  8 | 馬小跳 |  25 |   1 | 7000.00  | 2020-01-01 |       3 |   1 | 研發部 |
|  8 | 馬小跳 |  25 |   1 | 7000.00  | 2020-01-01 |       3 |   2 | 人事部 |
|  8 | 馬小跳 |  25 |   1 | 7000.00  | 2020-01-01 |       3 |   3 | 測試部 |
|  8 | 馬小跳 |  25 |   1 | 7000.00  | 2020-01-01 |       3 |   4 | 銷售部 |
|  8 | 馬小跳 |  25 |   1 | 7000.00  | 2020-01-01 |       3 |   5 | 生產部 |
|  9 | 張大騷 |  30 |   1 | 9000.00  | 2020-01-07 |       3 |   1 | 研發部 |
|  9 | 張大騷 |  30 |   1 | 9000.00  | 2020-01-07 |       3 |   2 | 人事部 |
|  9 | 張大騷 |  30 |   1 | 9000.00  | 2020-01-07 |       3 |   3 | 測試部 |
|  9 | 張大騷 |  30 |   1 | 9000.00  | 2020-01-07 |       3 |   4 | 銷售部 |
|  9 | 張大騷 |  30 |   1 | 9000.00  | 2020-01-07 |       3 |   5 | 生產部 |
| 10 | 馬冬梅 |  31 |   2 | 5000.00  | 2020-01-07 |       4 |   1 | 研發部 |
| 10 | 馬冬梅 |  31 |   2 | 5000.00  | 2020-01-07 |       4 |   2 | 人事部 |
| 10 | 馬冬梅 |  31 |   2 | 5000.00  | 2020-01-07 |       4 |   3 | 測試部 |
| 10 | 馬冬梅 |  31 |   2 | 5000.00  | 2020-01-07 |       4 |   4 | 銷售部 |
| 10 | 馬冬梅 |  31 |   2 | 5000.00  | 2020-01-07 |       4 |   5 | 生產部 |
| 11 | 川堅果 |  60 |   1 | 100.00   | 2020-01-08 | NULL    |   1 | 研發部 |
| 11 | 川堅果 |  60 |   1 | 100.00   | 2020-01-08 | NULL    |   2 | 人事部 |
| 11 | 川堅果 |  60 |   1 | 100.00   | 2020-01-08 | NULL    |   3 | 測試部 |
| 11 | 川堅果 |  60 |   1 | 100.00   | 2020-01-08 | NULL    |   4 | 銷售部 |
| 11 | 川堅果 |  60 |   1 | 100.00   | 2020-01-08 | NULL    |   5 | 生產部 |
+----+-----------+-----+-----+----------+------------+---------+-----+-----------+
55 rows in set (0.00 sec)

正確的查詢方式是:以兩表中相互關聯的字段作爲查詢條件進行查詢。

mysql> select * from employee,dept where employee.dept_id = dept.did;

查詢結果

+----+-----------+-----+-----+----------+------------+---------+-----+-----------+
| id | name      | age | sex | salary   | hire_date  | dept_id | did | dname     |
+----+-----------+-----+-----+----------+------------+---------+-----+-----------+
|  1 | 菜虛鯤 |  20 |   2 | 10000.00 | 2020-01-10 |       1 |   1 | 研發部 |
|  2 | 奧力給 |  30 |   1 | 18000.00 | 2020-01-08 |       1 |   1 | 研發部 |
|  3 | 老八    |  28 |   1 | 7000.00  | 2020-01-07 |       1 |   1 | 研發部 |
|  4 | 小張    |  25 |   1 | 8000.00  | 2020-01-10 |       1 |   1 | 研發部 |
|  5 | 小紅    |  20 |   2 | 6000.00  | 2020-01-05 |       2 |   2 | 人事部 |
|  6 | 小麗    |  23 |   2 | 6500.00  | 2020-01-05 |       2 |   2 | 人事部 |
|  7 | 小花    |  21 |   2 | 5500.00  | 2020-01-10 |       2 |   2 | 人事部 |
|  8 | 馬小跳 |  25 |   1 | 7000.00  | 2020-01-01 |       3 |   3 | 測試部 |
|  9 | 張大騷 |  30 |   1 | 9000.00  | 2020-01-07 |       3 |   3 | 測試部 |
| 10 | 馬冬梅 |  31 |   2 | 5000.00  | 2020-01-07 |       4 |   4 | 銷售部 |
+----+-----------+-----+-----+----------+------------+---------+-----+-----------+
10 rows in set (0.00 sec)

輸出結果爲兩個集合的交集。
在這裏插入圖片描述

3. Innner內連接查詢

3.1 語法

select 字段1,字段2... from1 inner join2 on [條件];

3.2 實戰

查詢員工和部門信息

select * from employee inner join dept on employee.dept_id = dept.did; 

輸出結果

mysql> select * from employee inner join dept on employee.dept_id = dept.did; 
+----+-----------+-----+-----+----------+------------+---------+-----+-----------+
| id | name      | age | sex | salary   | hire_date  | dept_id | did | dname     |
+----+-----------+-----+-----+----------+------------+---------+-----+-----------+
|  1 | 菜虛鯤 |  20 |   2 | 10000.00 | 2020-01-10 |       1 |   1 | 研發部 |
|  2 | 奧力給 |  30 |   1 | 18000.00 | 2020-01-08 |       1 |   1 | 研發部 |
|  3 | 老八    |  28 |   1 | 7000.00  | 2020-01-07 |       1 |   1 | 研發部 |
|  4 | 小張    |  25 |   1 | 8000.00  | 2020-01-10 |       1 |   1 | 研發部 |
|  5 | 小紅    |  20 |   2 | 6000.00  | 2020-01-05 |       2 |   2 | 人事部 |
|  6 | 小麗    |  23 |   2 | 6500.00  | 2020-01-05 |       2 |   2 | 人事部 |
|  7 | 小花    |  21 |   2 | 5500.00  | 2020-01-10 |       2 |   2 | 人事部 |
|  8 | 馬小跳 |  25 |   1 | 7000.00  | 2020-01-01 |       3 |   3 | 測試部 |
|  9 | 張大騷 |  30 |   1 | 9000.00  | 2020-01-07 |       3 |   3 | 測試部 |
| 10 | 馬冬梅 |  31 |   2 | 5000.00  | 2020-01-07 |       4 |   4 | 銷售部 |
+----+-----------+-----+-----+----------+------------+---------+-----+-----------+
10 rows in set (0.04 sec)

其輸出結果和多表聯合查詢一致。
在這裏插入圖片描述
如果附加其他條件,可以直接用and連接符連接在on語句的後面

mysql> select * from employee inner join dept on employee.dept_id = dept.did and employee.salary >= 10000; 

輸出結果

+----+-----------+-----+-----+----------+------------+---------+-----+-----------+
| id | name      | age | sex | salary   | hire_date  | dept_id | did | dname     |
+----+-----------+-----+-----+----------+------------+---------+-----+-----------+
|  1 | 菜虛鯤 |  20 |   2 | 10000.00 | 2020-01-10 |       1 |   1 | 研發部 |
|  2 | 奧力給 |  30 |   1 | 18000.00 | 2020-01-08 |       1 |   1 | 研發部 |
+----+-----------+-----+-----+----------+------------+---------+-----+-----------+
2 rows in set (0.00 sec)

4. Left左外連接查詢

左外連接查詢,即左表的數據全部顯示。

4.1 語法

select * from1 left join2 on [條件];

4.2 實戰

查詢員工和部門的所有信息

select * from employee left join dept on employee.dept_id = dept.did;

輸出結果

mysql> select * from employee left join dept on employee.dept_id = dept.did;
+----+-----------+-----+-----+----------+------------+---------+------+-----------+
| id | name      | age | sex | salary   | hire_date  | dept_id | did  | dname     |
+----+-----------+-----+-----+----------+------------+---------+------+-----------+
|  1 | 菜虛鯤 |  20 |   2 | 10000.00 | 2020-01-10 |       1 |    1 | 研發部 |
|  2 | 奧力給 |  30 |   1 | 18000.00 | 2020-01-08 |       1 |    1 | 研發部 |
|  3 | 老八    |  28 |   1 | 7000.00  | 2020-01-07 |       1 |    1 | 研發部 |
|  4 | 小張    |  25 |   1 | 8000.00  | 2020-01-10 |       1 |    1 | 研發部 |
|  5 | 小紅    |  20 |   2 | 6000.00  | 2020-01-05 |       2 |    2 | 人事部 |
|  6 | 小麗    |  23 |   2 | 6500.00  | 2020-01-05 |       2 |    2 | 人事部 |
|  7 | 小花    |  21 |   2 | 5500.00  | 2020-01-10 |       2 |    2 | 人事部 |
|  8 | 馬小跳 |  25 |   1 | 7000.00  | 2020-01-01 |       3 |    3 | 測試部 |
|  9 | 張大騷 |  30 |   1 | 9000.00  | 2020-01-07 |       3 |    3 | 測試部 |
| 10 | 馬冬梅 |  31 |   2 | 5000.00  | 2020-01-07 |       4 |    4 | 銷售部 |
| 11 | 川堅果 |  60 |   1 | 100.00   | 2020-01-08 | NULL    | NULL | NULL      |
+----+-----------+-----+-----+----------+------------+---------+------+-----------+
11 rows in set (0.00 sec)

左表中的數據全部顯示,右表中的數據只顯示符合條件的,不符合條件的以NULL填充。
在這裏插入圖片描述
更直觀的展現上述關係

mysql> select * from employee left join dept on employee.dept_id = dept.did and dept.did = 1;
+----+-----------+-----+-----+----------+------------+---------+------+-----------+
| id | name      | age | sex | salary   | hire_date  | dept_id | did  | dname     |
+----+-----------+-----+-----+----------+------------+---------+------+-----------+
|  1 | 菜虛鯤 |  20 |   2 | 10000.00 | 2020-01-10 |       1 |    1 | 研發部 |
|  2 | 奧力給 |  30 |   1 | 18000.00 | 2020-01-08 |       1 |    1 | 研發部 |
|  3 | 老八    |  28 |   1 | 7000.00  | 2020-01-07 |       1 |    1 | 研發部 |
|  4 | 小張    |  25 |   1 | 8000.00  | 2020-01-10 |       1 |    1 | 研發部 |
|  5 | 小紅    |  20 |   2 | 6000.00  | 2020-01-05 |       2 | NULL | NULL      |
|  6 | 小麗    |  23 |   2 | 6500.00  | 2020-01-05 |       2 | NULL | NULL      |
|  7 | 小花    |  21 |   2 | 5500.00  | 2020-01-10 |       2 | NULL | NULL      |
|  8 | 馬小跳 |  25 |   1 | 7000.00  | 2020-01-01 |       3 | NULL | NULL      |
|  9 | 張大騷 |  30 |   1 | 9000.00  | 2020-01-07 |       3 | NULL | NULL      |
| 10 | 馬冬梅 |  31 |   2 | 5000.00  | 2020-01-07 |       4 | NULL | NULL      |
| 11 | 川堅果 |  60 |   1 | 100.00   | 2020-01-08 | NULL    | NULL | NULL      |
+----+-----------+-----+-----+----------+------------+---------+------+-----------+
11 rows in set (0.01 sec)

5. Right右外連接查詢

右外連接查詢,與左外連接查詢正好相反,即右表的數據全部顯示。

5.1 語法

select * from1 right join2 on [條件];

5.2 實戰

查詢員工和部門信息

select * from employee right join dept on employee.dept_id = dept.did;

輸出結果

mysql> select * from employee right join dept on employee.dept_id = dept.did;
+------+-----------+------+------+----------+------------+---------+-----+-----------+
| id   | name      | age  | sex  | salary   | hire_date  | dept_id | did | dname     |
+------+-----------+------+------+----------+------------+---------+-----+-----------+
|    1 | 菜虛鯤 |   20 |    2 | 10000.00 | 2020-01-10 |       1 |   1 | 研發部 |
|    2 | 奧力給 |   30 |    1 | 18000.00 | 2020-01-08 |       1 |   1 | 研發部 |
|    3 | 老八    |   28 |    1 | 7000.00  | 2020-01-07 |       1 |   1 | 研發部 |
|    4 | 小張    |   25 |    1 | 8000.00  | 2020-01-10 |       1 |   1 | 研發部 |
|    5 | 小紅    |   20 |    2 | 6000.00  | 2020-01-05 |       2 |   2 | 人事部 |
|    6 | 小麗    |   23 |    2 | 6500.00  | 2020-01-05 |       2 |   2 | 人事部 |
|    7 | 小花    |   21 |    2 | 5500.00  | 2020-01-10 |       2 |   2 | 人事部 |
|    8 | 馬小跳 |   25 |    1 | 7000.00  | 2020-01-01 |       3 |   3 | 測試部 |
|    9 | 張大騷 |   30 |    1 | 9000.00  | 2020-01-07 |       3 |   3 | 測試部 |
|   10 | 馬冬梅 |   31 |    2 | 5000.00  | 2020-01-07 |       4 |   4 | 銷售部 |
| NULL | NULL      | NULL | NULL | NULL     | NULL       | NULL    |   5 | 生產部 |
+------+-----------+------+------+----------+------------+---------+-----+-----------+
11 rows in set (0.00 sec)

6. UNION全連接查詢

全連接查詢:其結果是在內連接查詢的基礎上顯示左右兩邊沒有的數據。
寫法:左連接查詢 UNION 右連接查詢

6.1 語法

select * from1 left join2 on [條件]
union
select * from1 right join2 on [條件]

6.2 實戰

以全連接的形式查詢部門和員工數據

select * from employee left join dept on employee.dept_id = dept.did
 union
select * from employee right join dept on employee.dept_id = dept.did;

輸出結果

mysql> select * from employee left join dept on employee.dept_id = dept.did
    -> union
    -> select * from employee right join dept on employee.dept_id = dept.did;
+------+-----------+------+------+----------+------------+---------+------+-----------+
| id   | name      | age  | sex  | salary   | hire_date  | dept_id | did  | dname     |
+------+-----------+------+------+----------+------------+---------+------+-----------+
|    1 | 菜虛鯤 |   20 |    2 | 10000.00 | 2020-01-10 |       1 |    1 | 研發部 |
|    2 | 奧力給 |   30 |    1 | 18000.00 | 2020-01-08 |       1 |    1 | 研發部 |
|    3 | 老八    |   28 |    1 | 7000.00  | 2020-01-07 |       1 |    1 | 研發部 |
|    4 | 小張    |   25 |    1 | 8000.00  | 2020-01-10 |       1 |    1 | 研發部 |
|    5 | 小紅    |   20 |    2 | 6000.00  | 2020-01-05 |       2 |    2 | 人事部 |
|    6 | 小麗    |   23 |    2 | 6500.00  | 2020-01-05 |       2 |    2 | 人事部 |
|    7 | 小花    |   21 |    2 | 5500.00  | 2020-01-10 |       2 |    2 | 人事部 |
|    8 | 馬小跳 |   25 |    1 | 7000.00  | 2020-01-01 |       3 |    3 | 測試部 |
|    9 | 張大騷 |   30 |    1 | 9000.00  | 2020-01-07 |       3 |    3 | 測試部 |
|   10 | 馬冬梅 |   31 |    2 | 5000.00  | 2020-01-07 |       4 |    4 | 銷售部 |
|   11 | 川堅果 |   60 |    1 | 100.00   | 2020-01-08 | NULL    | NULL | NULL      |
| NULL | NULL      | NULL | NULL | NULL     | NULL       | NULL    |    5 | 生產部 |
+------+-----------+------+------+----------+------------+---------+------+-----------+
12 rows in set (0.00 sec)

7. 嵌套查詢

嵌套查詢:在一個sql語句中使用多個select,第一次的查詢結果可作爲第二次查詢結果的條件/表名使用。

7.1 作爲表名使用

select * from (select id,name,age from employee) as em where em.id = 1;

查詢結果

mysql> select * from (select id,name,age from employee) as em where em.id = 1;
+----+-----------+-----+
| id | name      | age |
+----+-----------+-----+
|  1 | 菜虛鯤 |  20 |
+----+-----------+-----+
1 row in set (0.00 sec)

解釋:把(select id,name,age from employee)語句的返回結果當作一個臨時表,臨時表的表名爲em。

舉例:查詢平均工資在7000以上的部門
解題思路:
第一步,求部門平均工資

mysql> select AVG(salary) as ag,dept.dname from employee,dept where employee.dept_id = dept.did group by dept.did;
+--------------+-----------+
| ag           | dname     |
+--------------+-----------+
| 10750.000000 | 研發部 |
| 6000.000000  | 人事部 |
| 8000.000000  | 測試部 |
| 5000.000000  | 銷售部 |
+--------------+-----------+
4 rows in set (0.00 sec)

第二步,把部門平均工資表當作臨時表,進行查詢。

select dname from 
		(
			select 
				AVG(salary) as ag,
				dept.dname 
				from employee,dept w
				here employee.dept_id = dept.did 
				group by dept.did
		) as dept_avg_salary 
	where dept_avg_salary.ag > 7000;

運行結果:

mysql> select dname from (select AVG(salary) as ag,dept.dname from employee,dept where employee.dept_id = dept.did group by dept.did) as dept_avg_salary where dept_avg_salary.ag > 7000;
+-----------+
| dname     |
+-----------+
| 研發部 |
| 測試部 |
+-----------+
2 rows in set (0.00 sec)

7.2 作爲查詢條件使用

舉例:找出工資最高的員工的所有信息

select * from employee,dept 
	where employee.dept_id = dept.did 
	and employee.salary = (select MAX(salary) from employee);

查詢結果

mysql> select * from employee,dept where employee.dept_id = dept.did and employee.salary = (select MAX(salary) from employee);
+----+-----------+-----+-----+----------+------------+---------+-----+-----------+
| id | name      | age | sex | salary   | hire_date  | dept_id | did | dname     |
+----+-----------+-----+-----+----------+------------+---------+-----+-----------+
|  2 | 奧力給 |  30 |   1 | 18000.00 | 2020-01-08 |       1 |   1 | 研發部 |
+----+-----------+-----+-----+----------+------------+---------+-----+-----------+
1 row in set (0.01 sec)

舉例:求工資大於所有人平均工資的員工的所有信息

select * from employee,dept 
	where employee.dept_id = dept.did 
	and employee.salary > (select AVG(salary) from employee);

查詢結果

mysql> select * from employee,dept where employee.dept_id = dept.did and employee.salary > (select AVG(salary) from employee);
+----+-----------+-----+-----+----------+------------+---------+-----+-----------+
| id | name      | age | sex | salary   | hire_date  | dept_id | did | dname     |
+----+-----------+-----+-----+----------+------------+---------+-----+-----------+
|  1 | 菜虛鯤 |  20 |   2 | 10000.00 | 2020-01-10 |       1 |   1 | 研發部 |
|  2 | 奧力給 |  30 |   1 | 18000.00 | 2020-01-08 |       1 |   1 | 研發部 |
|  4 | 小張    |  25 |   1 | 8000.00  | 2020-01-10 |       1 |   1 | 研發部 |
|  9 | 張大騷 |  30 |   1 | 9000.00  | 2020-01-07 |       3 |   3 | 測試部 |
+----+-----------+-----+-----+----------+------------+---------+-----+-----------+
4 rows in set (0.00 sec)

7.3. 嵌套查詢關鍵字

7.3.1 ANY、SOME

兩者意義相同,與比較運算符(=、>、>=、<、<=、<>)結合起來使用,any/some作用於子查詢語句,只要子查詢語句中有一個符合條件,就返回true。

select s1 from t1 where s1 > any (select s1 from t2);

假設子查詢語句返回結果有三個result1,result2,result3,則上述語句等同於:

select s1 from t1 where s1 > result1 or s1 > result2 or s1 > result3;

7.3.2 IN

in 與 =any 相同。相當於:

select s1 from t1 where s1 = result1 or s1 = result2 or s1 = result3;

7.3.3 ALL

當子查詢語句中的所有項都符合條件時,才返回true。

select s1 from t1 where s1 > all (select s1 from t2);

等同於:

select s1 from t1 where s1 > result1 and s1 > result2 and s1 > result3;

7.3.4 EXISTS、NOT EXISTS

語法:

select ... from tableName exists(subquery);

當子查詢語句subquery返回列時,exists表達式爲true,此時執行前面的查詢語句。子查詢語句沒有返回任何列時,exists語句爲false,不執行前面的查詢語句。

mysql> select * from employee where exists (select * from employee where id =1);
+----+-----------+-----+-----+----------+------------+---------+
| id | name      | age | sex | salary   | hire_date  | dept_id |
+----+-----------+-----+-----+----------+------------+---------+
|  1 | 菜虛鯤 |  20 |   2 | 10000.00 | 2020-01-10 |       1 |
|  2 | 奧力給 |  30 |   1 | 18000.00 | 2020-01-08 |       1 |
|  3 | 老八    |  28 |   1 | 7000.00  | 2020-01-07 |       1 |
|  4 | 小張    |  25 |   1 | 8000.00  | 2020-01-10 |       1 |
|  5 | 小紅    |  20 |   2 | 6000.00  | 2020-01-05 |       2 |
|  6 | 小麗    |  23 |   2 | 6500.00  | 2020-01-05 |       2 |
|  7 | 小花    |  21 |   2 | 5500.00  | 2020-01-10 |       2 |
|  8 | 馬小跳 |  25 |   1 | 7000.00  | 2020-01-01 |       3 |
|  9 | 張大騷 |  30 |   1 | 9000.00  | 2020-01-07 |       3 |
| 10 | 馬冬梅 |  31 |   2 | 5000.00  | 2020-01-07 |       4 |
| 11 | 川堅果 |  60 |   1 | 100.00   | 2020-01-08 | NULL    |
+----+-----------+-----+-----+----------+------------+---------+
11 rows in set (0.00 sec)

當子查詢語句沒有返回任何列時

mysql> select * from employee where exists (select * from employee where id =12);
Empty set

select NULL 返回了列,所以:

mysql> select NULL;
+------+
| NULL |
+------+
| NULL |
+------+
1 row in set (0.00 sec)
 
mysql> select * from employee where exists (select NULL) and salary > 10000;
+----+-----------+-----+-----+----------+------------+---------+
| id | name      | age | sex | salary   | hire_date  | dept_id |
+----+-----------+-----+-----+----------+------------+---------+
|  2 | 奧力給 |  30 |   1 | 18000.00 | 2020-01-08 |       1 |
+----+-----------+-----+-----+----------+------------+---------+
1 row in set (0.00 sec)

not exists與exists相反。

8 判斷查詢

8.1 IF

語法:

if(條件表達式,"結果爲true","結果爲false");

舉例,將薪資大於大於8000的員工薪資級別設置爲小康,小於8000設置爲一般:

select *,if(salary > 8000,"小康","一般") as salary_level from employee;

輸出結果:

mysql> select *,if(salary > 8000,"小康","一般") as salary_level from employee;
+----+-----------+-----+-----+----------+------------+---------+--------------+
| id | name      | age | sex | salary   | hire_date  | dept_id | salary_level |
+----+-----------+-----+-----+----------+------------+---------+--------------+
|  1 | 菜虛鯤 |  20 |   2 | 10000.00 | 2020-01-10 |       1 | 小康       |
|  2 | 奧力給 |  30 |   1 | 18000.00 | 2020-01-08 |       1 | 小康       |
|  3 | 老八    |  28 |   1 | 7000.00  | 2020-01-07 |       1 | 一般       |
|  4 | 小張    |  25 |   1 | 8000.00  | 2020-01-10 |       1 | 一般       |
|  5 | 小紅    |  20 |   2 | 6000.00  | 2020-01-05 |       2 | 一般       |
|  6 | 小麗    |  23 |   2 | 6500.00  | 2020-01-05 |       2 | 一般       |
|  7 | 小花    |  21 |   2 | 5500.00  | 2020-01-10 |       2 | 一般       |
|  8 | 馬小跳 |  25 |   1 | 7000.00  | 2020-01-01 |       3 | 一般       |
|  9 | 張大騷 |  30 |   1 | 9000.00  | 2020-01-07 |       3 | 小康       |
| 10 | 馬冬梅 |  31 |   2 | 5000.00  | 2020-01-07 |       4 | 一般       |
| 11 | 川堅果 |  60 |   1 | 100.00   | 2020-01-08 | NULL    | 一般       |
+----+-----------+-----+-----+----------+------------+---------+--------------+
11 rows in set (0.00 sec)

8.2 if … else if … else 形式

語法:

select ...,case when [條件1] then [result]
				when [條件2] then [result]
				else [result]
				end
from tableName;

舉例:
根據員工工資劃分員工生活水平,小於7000爲貧窮,7000 到 9000爲一般,9000-10000爲中等,10000-12000爲中等偏上,大於12000爲有錢。

mysql> select name,salary,case  when salary < 7000 then '貧窮'
    -> 							when salary < 9000 then '一般'
    -> 							when salary < 10000 then '中等'
    -> 							when salary < 12000 then '中等偏上'
    -> 							else '有錢'
    -> 					  end as living_standard
    -> from employee;
+-----------+----------+-----------------+
| name      | salary   | living_standard |
+-----------+----------+-----------------+
| 菜虛鯤 | 10000.00 | 中等偏上    |
| 奧力給 | 18000.00 | 有錢          |
| 老八    | 7000.00  | 一般          |
| 小張    | 8000.00  | 一般          |
| 小紅    | 6000.00  | 貧窮          |
| 小麗    | 6500.00  | 貧窮          |
| 小花    | 5500.00  | 貧窮          |
| 馬小跳 | 7000.00  | 一般          |
| 張大騷 | 9000.00  | 中等          |
| 馬冬梅 | 5000.00  | 貧窮          |
| 川堅果 | 100.00   | 貧窮          |
+-----------+----------+-----------------+
11 rows in set (0.00 sec)

其形式類似於if…else if…else if…else形式。

8.3 switch case形式

語法:

select ..., case s1
			when [value1] then [result1]
			when [value2] then [result2]
			when [value3] then [result3]
			else [resultOther] end
from tableName;

舉例,直接顯示出員工性別:

mysql> select *,case sex
    -> 				when 1 then '男'
    -> 				when 2 then '女'
    -> 				else '未知' end as employee_sex
    -> from employee;
+----+-----------+-----+-----+----------+------------+---------+--------------+
| id | name      | age | sex | salary   | hire_date  | dept_id | employee_sex |
+----+-----------+-----+-----+----------+------------+---------+--------------+
|  1 | 菜虛鯤 |  20 |   2 | 10000.00 | 2020-01-10 |       1 ||
|  2 | 奧力給 |  30 |   1 | 18000.00 | 2020-01-08 |       1 ||
|  3 | 老八    |  28 |   1 | 7000.00  | 2020-01-07 |       1 ||
|  4 | 小張    |  25 |   1 | 8000.00  | 2020-01-10 |       1 ||
|  5 | 小紅    |  20 |   2 | 6000.00  | 2020-01-05 |       2 ||
|  6 | 小麗    |  23 |   2 | 6500.00  | 2020-01-05 |       2 ||
|  7 | 小花    |  21 |   2 | 5500.00  | 2020-01-10 |       2 ||
|  8 | 馬小跳 |  25 |   1 | 7000.00  | 2020-01-01 |       3 ||
|  9 | 張大騷 |  30 |   1 | 9000.00  | 2020-01-07 |       3 ||
| 10 | 馬冬梅 |  31 |   2 | 5000.00  | 2020-01-07 |       4 ||
| 11 | 川堅果 |  60 |   1 | 100.00   | 2020-01-08 | NULL    ||
+----+-----------+-----+-----+----------+------------+---------+--------------+
11 rows in set (0.00 sec)

參考鏈接

發佈了41 篇原創文章 · 獲贊 18 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章