MySQL學習——SQL查詢語句(連接查詢&子查詢)(三)
一:連接查詢:
連接查詢是將倆個或者倆個以上的表按照某個條件連接起來,從中選擇需要的數據,連接查詢同時查詢倆個或者倆個以上的表時使用,當不同的表中存在表示相同意義的字段時,可以通過該字段來連接這幾個表,例如,學生表中有course_id字段來表示所學課程的課程號,課程表中有num字段來表示課程號,那麽可以通過學生表中的course_id字段與課程表中的num字段來進行連接查詢,連接查詢包括內連接查詢和外連接查詢。
1.1 內連接查詢
內連接查詢是一種常用的連接查詢,內連接查詢可以查詢倆個或者以上的表。
註:倆個表中表示相同意思的字段可以是指父表的主鍵和字表的外鍵;
例:創建倆個示例表employee和department
mysql> mysql> show create table department\G *************************** 1. row *************************** Table: department Create Table: CREATE TABLE `department` ( `d_id` int(11) DEFAULT NULL, `d_name` varchar(20) DEFAULT NULL, `function` varchar(20) DEFAULT NULL, `address` varchar(20) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 1 row in set (0.00 sec) mysql> show create table employee\G *************************** 1. row *************************** Table: employee Create Table: CREATE TABLE `employee` ( `num` int(11) DEFAULT NULL, `d_id` int(11) DEFAULT NULL, `name` varchar(20) DEFAULT NULL, `age` int(11) DEFAULT NULL, `sex` char(4) DEFAULT NULL, `homeaddr` varchar(20) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 1 row in set (0.00 sec) mysql> desc employee; +----------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +----------+-------------+------+-----+---------+-------+ | num | int(11) | YES | | NULL | | | d_id | int(11) | YES | | NULL | | | name | varchar(20) | YES | | NULL | | | age | int(11) | YES | | NULL | | | sex | char(4) | YES | | NULL | | | homeaddr | varchar(20) | YES | | NULL | | +----------+-------------+------+-----+---------+-------+ 6 rows in set (0.00 sec) mysql> desc department; +----------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +----------+-------------+------+-----+---------+-------+ | d_id | int(11) | YES | | NULL | | | d_name | varchar(20) | YES | | NULL | | | function | varchar(20) | YES | | NULL | | | address | varchar(20) | YES | | NULL | | +----------+-------------+------+-----+---------+-------+ 4 rows in set (0.00 sec) mysql>
插入實驗所需數據:
mysql> select * from employee,department; +------+------+--------+------+------+--------------------+------+-----------+--------------+---------------------+ | num | d_id | name | age | sex | homeaddr | d_id | d_name | function | address | +------+------+--------+------+------+--------------------+------+-----------+--------------+---------------------+ | 1 | 1001 | 張三 | 26 | 男 | 北京市海定區 | 1001 | 科研部 | 研發產品 | 3號樓5層 | | 1 | 1001 | 張三 | 26 | 男 | 北京市海定區 | 1002 | 生 | 生產產品 | 5號樓1層 | | 1 | 1001 | 張三 | 26 | 男 | 北京市海定區 | 1003 | 銷售部 | 策劃銷售 | 1號樓銷售大廳 | | 2 | 1002 | 李四 | 24 | 女 | 北京市昌平區 | 1001 | 科研部 | 研發產品 | 3號樓5層 | | 2 | 1002 | 李四 | 24 | 女 | 北京市昌平區 | 1002 | 生 | 生產產品 | 5號樓1層 | | 2 | 1002 | 李四 | 24 | 女 | 北京市昌平區 | 1003 | 銷售部 | 策劃銷售 | 1號樓銷售大廳 | | 3 | 1001 | 王五 | 24 | 男 | 湖南長沙市 | 1001 | 科研部 | 研發產品 | 3號樓5層 | | 3 | 1001 | 王五 | 24 | 男 | 湖南長沙市 | 1002 | 生 | 生產產品 | 5號樓1層 | | 3 | 1001 | 王五 | 24 | 男 | 湖南長沙市 | 1003 | 銷售部 | 策劃銷售 | 1號樓銷售大廳 | | 4 | 1004 | Aric | 15 | 男 | England | 1001 | 科研部 | 研發產品 | 3號樓5層 | | 4 | 1004 | Aric | 15 | 男 | England | 1002 | 生 | 生產產品 | 5號樓1層 | | 4 | 1004 | Aric | 15 | 男 | England | 1003 | 銷售部 | 策劃銷售 | 1號樓銷售大廳 | +------+------+--------+------+------+--------------------+------+-----------+--------------+---------------------+ 12 rows in set (0.00 sec) mysql>
查詢結果顯示employee表和department表的d_id字段都表示部門號,通過d_id字段可以將employee表和department表進行內連接查詢,從employee表中查詢出num,name,d_id,age和sex這幾個字段。
mysql>
mysql> select num,name,employee.d_id,age,sex,d_name,function from employee,department where employee.d_id = department.d_id;
+------+--------+------+------+------+-----------+--------------+
| num | name | d_id | age | sex | d_name | function |
+------+--------+------+------+------+-----------+--------------+
| 1 | 張三 | 1001 | 26 | 男 | 科研部 | 研發產品 |
| 2 | 李四 | 1002 | 24 | 女 | 生 | 生產產品 |
| 3 | 王五 | 1001 | 24 | 男 | 科研部 | 研發產品 |
+------+--------+------+------+------+-----------+--------------+
3 rows in set (0.00 sec)
mysql>
1.2 外連接查詢
外連接查詢可以查詢倆個或者倆個以上的表,外連接查詢也需要通過制定字段來進行連接,當該字段取值相等時,可以查詢出該記錄,而且該字段取值不相等的記錄也可以查詢出來,外連接查詢包括左連接查詢和右連接查詢。
格式: SELECT 屬性列表 FROM 表名1 LEFT | RIGHT JOIN 表名2 ON 表名1屬性=表名2屬性;
1.2.1 左連接查詢
使用左連接查詢employee和department倆表,通過d_id字段進行連接;
mysql>
mysql> select num,name,employee.d_id,age,sex,d_name,function from employee LEFT JOIN department on employee.d_id=department.d_id;
+------+--------+------+------+------+-----------+--------------+
| num | name | d_id | age | sex | d_name | function |
+------+--------+------+------+------+-----------+--------------+
| 1 | 張三 | 1001 | 26 | 男 | 科研部 | 研發產品 |
| 3 | 王五 | 1001 | 24 | 男 | 科研部 | 研發產品 |
| 2 | 李四 | 1002 | 24 | 女 | 生 | 生產產品 |
| 4 | Aric | 1004 | 15 | 男 | NULL | NULL |
+------+--------+------+------+------+-----------+--------------+
4 rows in set (0.00 sec)
mysql>
1.2.2 右連接查詢
使用右連接查詢employee和department倆表,通過d_id字段進行連接;
mysql> select num,name,age,sex,department.d_id,d_name,function from employee RIGHT JOIN department on employee.d_id=department.d_id;
+------+--------+------+------+------+-----------+--------------+
| num | name | age | sex | d_id | d_name | function |
+------+--------+------+------+------+-----------+--------------+
| 1 | 張三 | 26 | 男 | 1001 | 科研部 | 研發產品 |
| 2 | 李四 | 24 | 女 | 1002 | 生 | 生產產品 |
| 3 | 王五 | 24 | 男 | 1001 | 科研部 | 研發產品 |
| NULL | NULL | NULL | NULL | 1003 | 銷售部 | 策劃銷售 |
+------+--------+------+------+------+-----------+--------------+
4 rows in set (0.00 sec)
mysql>
1.2.3 復合條件查詢
在連接查詢時,也可以增加其他的限制條件,通過多個條件的復合查詢,可以使查詢結果更加準確。
例如:使用內連接的方式查詢employee表和department表,並且employee表中的age字段的值必須大於24.
mysql>
mysql> select num,name,employee.d_id,age,sex,d_name,function
-> from employee,department
-> where employee.d_id = department.d_id
-> and age>24;
+------+--------+------+------+------+-----------+--------------+
| num | name | d_id | age | sex | d_name | function |
+------+--------+------+------+------+-----------+--------------+
| 1 | 張三 | 1001 | 26 | 男 | 科研部 | 研發產品 |
+------+--------+------+------+------+-----------+--------------+
1 row in set (0.00 sec)
mysql>
mysql>
mysql> select num,name,employee.d_id,age,sex,d_name,function from employee,department where employee.d_id = department.d_id having age>24;
+------+--------+------+------+------+-----------+--------------+
| num | name | d_id | age | sex | d_name | function |
+------+--------+------+------+------+-----------+--------------+
| 1 | 張三 | 1001 | 26 | 男 | 科研部 | 研發產品 |
+------+--------+------+------+------+-----------+--------------+
1 row in set (0.00 sec)
mysql>
例子:使用內連接的方式查詢employee表和department表,並且以age字段的升序方式顯示查詢結果
mysql>
mysql> select num,name,employee.d_id,age,sex,d_name,function
-> from employee,department
-> where employee.d_id=department.d_id
-> order by age ASC;
+------+--------+------+------+------+-----------+--------------+
| num | name | d_id | age | sex | d_name | function |
+------+--------+------+------+------+-----------+--------------+
| 3 | 王五 | 1001 | 24 | 男 | 科研部 | 研發產品 |
| 2 | 李四 | 1002 | 24 | 女 | 生 | 生產產品 |
| 1 | 張三 | 1001 | 26 | 男 | 科研部 | 研發產品 |
+------+--------+------+------+------+-----------+--------------+
3 rows in set (0.00 sec)
mysql>
二:子查詢
子查詢時將一個查詢語句嵌套在另一個查詢語句中,內層查詢語句的查詢結果,可以為外層查詢語句提供查詢條件,因為在特定的情況下,一個查詢語句的條件需要另外一個查詢語句來獲取,例如現在需要從學生成績表中查詢計算機系學生的各科成績,那麽首先就必須知道哪些課程是計算機系學生選修的,因此必須查詢計算機學生選修的課程,然後根據這些課程來查詢計算機系學生的各科成績,通過子查詢,可以實現多表之間的查詢,子查詢中可能包括IN,NOT IN,ANY,ALL,EXISTS和NOT EXSITS等關鍵字,子查詢中還可能包含比較運算符,如‘=’,‘!=’,‘>’等;
2.1帶IN關鍵字的子查詢
mysql> select * from employee
-> where d_id IN
-> (select d_id from department);
+------+------+--------+------+------+--------------------+
| num | d_id | name | age | sex | homeaddr |
+------+------+--------+------+------+--------------------+
| 1 | 1001 | 張三 | 26 | 男 | 北京市海定區 |
| 2 | 1002 | 李四 | 24 | 女 | 北京市昌平區 |
| 3 | 1001 | 王五 | 24 | 男 | 湖南長沙市 |
+------+------+--------+------+------+--------------------+
3 rows in set (0.00 sec)
mysql>
查詢employee表中的記錄,這些記錄的d_id字段必須沒有在department表中出現過。
mysql>
mysql> select * from employee
-> where d_id NOT IN
-> (select d_id from department );
+------+------+------+------+------+----------+
| num | d_id | name | age | sex | homeaddr |
+------+------+------+------+------+----------+
| 4 | 1004 | Aric | 15 | 男 | England |
+------+------+------+------+------+----------+
1 row in set (0.00 sec)
mysql>
2.2 帶比較運算符的子查詢
子查詢可以使用比較運算符(=,!=,>,<,>=,<=,<>)等
示例數據表
mysql> select * from computer_stu,scholarship;
+------+------+-------+-------+-------+
| id | name | score | level | score |
+------+------+-------+-------+-------+
| 1001 | Lily | 85 | 1 | 90 |
| 1001 | Lily | 85 | 2 | 80 |
| 1001 | Lily | 85 | 3 | 70 |
| 1002 | Tom | 91 | 1 | 90 |
| 1002 | Tom | 91 | 2 | 80 |
| 1002 | Tom | 91 | 3 | 70 |
| 1003 | Jim | 87 | 1 | 90 |
| 1003 | Jim | 87 | 2 | 80 |
| 1003 | Jim | 87 | 3 | 70 |
| 1004 | Aric | 77 | 1 | 90 |
| 1004 | Aric | 77 | 2 | 80 |
| 1004 | Aric | 77 | 3 | 70 |
| 1005 | Lucy | 65 | 1 | 90 |
| 1005 | Lucy | 65 | 2 | 80 |
| 1005 | Lucy | 65 | 3 | 70 |
| 1006 | Andy | 99 | 1 | 90 |
| 1006 | Andy | 99 | 2 | 80 |
| 1006 | Andy | 99 | 3 | 70 |
| 1007 | Ada | 85 | 1 | 90 |
| 1007 | Ada | 85 | 2 | 80 |
| 1007 | Ada | 85 | 3 | 70 |
| 1008 | Jeck | 70 | 1 | 90 |
| 1008 | Jeck | 70 | 2 | 80 |
| 1008 | Jeck | 70 | 3 | 70 |
+------+------+-------+-------+-------+
24 rows in set (0.00 sec)
mysql>
從computer_stu表中查詢獲得一等獎學金的學生的學號,姓名和分數
mysql>
mysql> select id,name,score from computer_stu where score >= (select score from scholarship where level=1);
+------+------+-------+
| id | name | score |
+------+------+-------+
| 1002 | Tom | 91 |
| 1006 | Andy | 99 |
+------+------+-------+
2 rows in set (0.00 sec)
mysql>
在department表中查詢那些部門沒有年齡為24歲的員工;
mysql> select d_id,d_name from department
-> where d_id NOT IN
-> (select d_id from employee where age=24);
+------+-----------+
| d_id | d_name |
+------+-----------+
| 1003 | 銷售部 |
+------+-----------+
1 row in set (0.00 sec)
mysql>
2.3 帶EXISTS 關鍵字的子查詢
EXISTS關鍵字表示存在,使用EXISTS關鍵字時,內層查詢不會反悔查詢記錄,而是返回一個真假值,當返回真是外層查詢語句進行查詢,當返回假時,外層語句不進行查詢或者查詢 不出任何結果。
例:如果department表中存在d_id取值為1003的記錄,則查詢employee表的記錄:
mysql>
mysql> select * from employee
-> where EXISTS
-> (select d_name from department where d_id =1003)
-> ;
+------+------+--------+------+------+--------------------+
| num | d_id | name | age | sex | homeaddr |
+------+------+--------+------+------+--------------------+
| 1 | 1001 | 張三 | 26 | 男 | 北京市海定區 |
| 2 | 1002 | 李四 | 24 | 女 | 北京市昌平區 |
| 3 | 1001 | 王五 | 24 | 男 | 湖南長沙市 |
| 4 | 1004 | Aric | 15 | 男 | England |
+------+------+--------+------+------+--------------------+
4 rows in set (0.00 sec)
mysql>
例:如果department表中存在d_id取值為1004的記錄,則查詢emloyee表的記錄;
mysql>
mysql> select * from employee
-> where EXISTS
-> (select d_name from department where d_id=0);
Empty set (0.00 sec)
mysql>
例:如果department表中存在d_id取值為1003的記錄,則查詢employee表中age大於24的記錄;
mysql>
mysql> select * from employee where age>24 and EXISTS
-> (select d_name from department where d_id=1003);
+------+------+--------+------+------+--------------------+
| num | d_id | name | age | sex | homeaddr |
+------+------+--------+------+------+--------------------+
| 1 | 1001 | 張三 | 26 | 男 | 北京市海定區 |
+------+------+--------+------+------+--------------------+
1 row in set (0.00 sec)
mysql>
2.4 帶ANY關鍵字的子查詢
ANY關鍵字表示滿足其中任一條件,使用ANY關鍵字時,是要滿足內層查詢語句返回的結果中的任何一個,就可以通過該條件來執行外層查詢語句。
例:查詢到底哪位同學能獲得獎學金:
mysql>
mysql> select * from computer_stu where score >= ANY
-> (select score from scholarship);
+------+------+-------+
| id | name | score |
+------+------+-------+
| 1001 | Lily | 85 |
| 1002 | Tom | 91 |
| 1003 | Jim | 87 |
| 1004 | Aric | 77 |
| 1006 | Andy | 99 |
| 1007 | Ada | 85 |
| 1008 | Jeck | 70 |
+------+------+-------+
7 rows in set (0.00 sec)
mysql>
2.5 帶ALL關鍵字的子查詢
ALL關鍵字表示滿足所有條件,使用ALL關鍵字時,只有滿足內層查詢語句返回的所有結果,才可以執行外層查詢語句。
例:從computer_stu表中查詢出那些同學可以獲得一等獎學金;
mysql>
mysql> select * from computer_stu
-> where score >= ALL
-> (select score from scholarship);
+------+------+-------+
| id | name | score |
+------+------+-------+
| 1002 | Tom | 91 |
| 1006 | Andy | 99 |
+------+------+-------+
2 rows in set (0.00 sec)
mysql>
註:ANY關鍵字和ALL關鍵字的使用方式是一樣的,但是倆這有很大的區別,使用ANY關鍵字時,只要滿足內層查詢語句返回的結果中的任何一個,就可以通過該條件來執行外層查詢語句,而ALL關鍵字剛好相反,只有滿足內層查詢語句返回的所有結果,才可以執行外層查詢語句。
附:合並查詢結果(具有去重功能)
合並查詢結果是將多個select語句的查詢結果合並在一起,因某種情況下,需要將幾個select語句查詢出來的結果合並起來顯示,例如現在需要查詢公司甲和公司乙這倆個公司所有的員工信息,然後將倆次的查詢結果合並到一起,進行合並操作使用 UNION和UNION ALL關鍵字。
格式:select 語句1
UNION | UNION ALL
select 語句2
UNION | UNION ALL
…………
例:從department表和employee表中查詢d_id字段的取值,然後通過UNION關鍵字將結果合並到一起。
mysql>
mysql>
mysql> select d_id from department
-> UNION
-> select d_id from employee;
+------+
| d_id |
+------+
| 1001 |
| 1002 |
| 1003 |
| 1004 |
+------+
4 rows in set (0.00 sec)
mysql>
MySQL學習——SQL查詢語句(連接查詢&子查詢)(三)