MySQL基本查詢【3/29】

MySQL基本查詢【3/29】

單表查詢、帶IN關鍵字的查詢、帶BETWEEN AND的範圍查詢、帶LIKE的字符匹配查詢、帶AND的多條件查詢等

MySQL基礎查詢【3月29日】

SELECT {* | <字段列表>}
[
FROM <表1>,<表2>…
[WHERE <表達式>]
[GROUP BY <group by definition>]
[HAVING <expression> [{<operator> <expression>}…]]
[ORDER BY <order by definition>]
[LIMIT [<offset>,] <row count>]
]
SELECT [字段1,字段2,…,字段n]
FROM [表或視圖]
WHERE [查詢條件]

{* | <字段列表>}包含星號通配符選字段列表,表示查詢的字段,其中字段列表至少包含一個字段名稱,如果要查詢多個字段,多個字段之間用“,”隔開,最後一個字段不加逗號。

FROM <表1>,<表2>…,表1和表2表示查詢數據的來源,可以是單個或多個。

WHERE子句是可選項,如果選擇該項,將限定查詢行必須滿足的查詢條件

GROUP BY<字段>,如何顯示查詢出來的數據,並按照指定的字段分組

[ORDER BY<字段>]按什麼樣的順序顯示查詢出來的數據,可以進行的排序有:升序(ASC),降序(DESC)

[LIMIT [<offset>,] <row count>]每次顯示查詢出來的數據條數。mysql> SELECT f_id, f_name FROM fruits;
±-----±----------+
| f_id | f_name |
±-----±----------+
| a1 | apple |
| a2 | apricot |
| b1 | blckberry |
| b2 | berry |
| b5 | xxxx |
| bs1 | orange |
| bs2 | melon |
| c0 | cherry |
| l2 | lemon |
| m1 | mango |
| m2 | xbabay |
| m3 | xxtt |
| o2 | cocount |
| t1 | banana |
| t2 | grape |
| t4 | xbababa |
±-----±----------+
16 rows in set (0.00 sec)

顯示的順序爲添加到表中的順序。

  • 單表查詢:

查詢所有字段:

1
SELECT * FROM 表名;

查詢指定字段:
SELECT 列名 FROM 表名;

查詢指定記錄:
SELECT 字段1,字段2,…,字段名n FROM 表名 WHERE 查詢條件

WHERE 條件判斷符

|操作符|說明
|------
|=|相等
|<>,!=|不相等
|<|小於
|<=|小於或等於
|>|大於
|>=|大於或者等於
|BETWEEN|位於兩值之間

比較數字:
mysql> SELECT f_name,f_price FROM fruits WHERE f_price = 10.2;

比較字符串:
mysql> SELECT f_name,f_price FROM fruits WHERE f_name = 'apple';

  • 帶IN關鍵字的查詢:

查詢滿足指定條件範圍的記錄:
mysql> SELECT s_id,f_name,f_price FROM fruits WHERE s_id IN (101,102) ORDER BY f_name;
±-----±----------±--------+
| s_id | f_name | f_price |
±-----±----------±--------+
| 101 | apple | 5.20 |
| 102 | banana | 10.30 |
| 101 | blckberry | 10.20 |
| 101 | cherry | 3.20 |
| 102 | grape | 5.30 |
| 102 | orange | 11.30 |
±-----±----------±--------+
6 rows in set (0.00 sec)

查詢不在指定範圍內的記錄:
mysql> SELECT s_id,f_name,f_price FROM fruits WHERE s_id NOT IN (101,102) ORDER BY f_name;
±-----±--------±--------+
| s_id | f_name | f_price |
±-----±--------±--------+
| 103 | apricot | 2.20 |
| 104 | berry | 7.60 |
| 103 | cocount | 9.20 |
| 104 | lemon | 6.40 |
| 106 | mango | 15.60 |
| 105 | melon | 8.20 |
| 107 | xbababa | 3.60 |
| 105 | xbabay | 2.60 |
| 105 | xxtt | 11.60 |
| 107 | xxxx | 3.60 |
±-----±--------±--------+
10 rows in set (0.00 sec)

  • 帶BETWEEN AND的範圍查詢
    mysql> SELECT f_name,f_price FROM fruits WHERE f_price BETWEEN 2.00 AND 10.20;
    ±----------±--------+
    | f_name | f_price |
    ±----------±--------+
    | apple | 5.20 |
    | apricot | 2.20 |
    | blckberry | 10.20 |
    | berry | 7.60 |
    | xxxx | 3.60 |
    | melon | 8.20 |
    | cherry | 3.20 |
    | lemon | 6.40 |
    | xbabay | 2.60 |
    | cocount | 9.20 |
    | grape | 5.30 |
    | xbababa | 3.60 |
    ±----------±--------+
    12 rows in set (0.00 sec)

    mysql> SELECT f_name,f_price FROM fruits WHERE f_price NOT BETWEEN 2.00 AND 10.20;
    ±-------±--------+
    | f_name | f_price |
    ±-------±--------+
    | orange | 11.30 |
    | mango | 15.60 |
    | xxtt | 11.60 |
    | banana | 10.30 |
    ±-------±--------+
    4 rows in set (0.00 sec)

  • 帶LIKE的字符匹配查詢:

**‘%’匹配任意長度的字符,甚至包括0字符,‘_’**一次只能匹配任意一個字符
mysql> SELECT f_id,f_name FROM fruits WHERE f_name LIKE 'b%';
±-----±----------+
| f_id | f_name |
±-----±----------+
| b1 | blckberry |
| b2 | berry |
| t1 | banana |
±-----±----------+
3 rows in set (0.00 sec)
mysql> SELECT f_id,f_name FROM fruits WHERE f_name LIKE '____y';
±-----±-------+
| f_id | f_name |
±-----±-------+
| b2 | berry |
±-----±-------+
1 row in set (0.00 sec)

查詢表結構
mysql> describe fruits;
±--------±-------------±-----±----±--------±------+
| Field | Type | Null | Key | Default | Extra |
±--------±-------------±-----±----±--------±------+
| f_id | char(10) | NO | PRI | NULL | |
| s_id | int(11) | NO | | NULL | |
| f_name | char(255) | NO | | NULL | |
| f_price | decimal(8,2) | NO | | NULL | |
±--------±-------------±-----±----±--------±------+
4 rows in set (0.01 sec)

查詢空值:空值指數據未知,不適用或將在以後添加數據

查詢計數
mysql> SELECT COUNT(*) AS cust_num FROM customers;
±---------+
| cust_num |
±---------+
| 4 |
±---------+
1 row in set (0.00 sec)

查詢空值
mysql> SELECT c_id,c_name,c_email FROM customers WHERE c_email IS NULL;
±------±---------±--------+
| c_id | c_name | c_email |
±------±---------±--------+
| 10003 | Netbhood | NULL |
±------±---------±--------+
1 row in set (0.00 sec)

查詢字段不爲空的記錄
mysql> SELECT c_id,c_name,c_email FROM customers WHERE c_email IS NOT NULL;
±------±--------±------------------+
| c_id | c_name | c_email |
±------±--------±------------------+
| 10001 | RedHook | [email protected] |
| 10002 | Stars | [email protected] |
| 10004 | JOTO | [email protected] |
±------±--------±------------------+
3 rows in set (0.00 sec)

  • 帶AND的多條件查詢:
    mysql> SELECT f_id,f_price,f_name FROM fruits WHERE s_id = '101' AND f_price >=5;
    ±-----±--------±----------+
    | f_id | f_price | f_name |
    ±-----±--------±----------+
    | a1 | 5.20 | apple |
    | b1 | 10.20 | blckberry |
    ±-----±--------±----------+
    2 rows in set (0.00 sec)

帶OR的多條件查詢,只要滿足其中一個條件記錄即返回
mysql> SELECT s_id,f_price,f_name FROM fruits WHERE s_id = 101 OR s_id = 102;
±-----±--------±----------+
| s_id | f_price | f_name |
±-----±--------±----------+
| 101 | 5.20 | apple |
| 101 | 10.20 | blckberry |
| 102 | 11.30 | orange |
| 101 | 3.20 | cherry |
| 102 | 10.30 | banana |
| 102 | 5.30 | grape |
±-----±--------±----------+
6 rows in set (0.00 sec)

OR操作符和IN操作符作用效果一樣,但IN快一些,且可以執行更加複雜的嵌套查詢。

AND的優先級高於OR,因此先對AND兩邊的操作數進行操作,再與OR中操作數結合。

  • 去重複操作
    mysql> SELECT DISTINCT s_id FROM fruits;
    ±-----+
    | s_id |
    ±-----+
    | 101 |
    | 103 |
    | 104 |
    | 107 |
    | 102 |
    | 105 |
    | 106 |
    ±-----+

對查詢結果進行排序
mysql> SELECT f_name FROM fruits ORDER BY f_name;
±----------+
| f_name |
±----------+
| apple |
| apricot |
| banana |
| berry |
| blckberry |
| cherry |
| cocount |
| grape |
| lemon |
| mango |
| melon |
| orange |
| xbababa |
| xbabay |
| xxtt |
| xxxx |
±----------+
16 rows in set (0.00 sec)

  • 多列排序
    mysql> SELECT f_name,f_price FROM fruits ORDER BY f_name,f_price;
    ±----------±--------+
    | f_name | f_price |
    ±----------±--------+
    | apple | 5.20 |
    | apricot | 2.20 |
    | banana | 10.30 |
    | berry | 7.60 |
    | blckberry | 10.20 |
    | cherry | 3.20 |
    | cocount | 9.20 |
    | grape | 5.30 |
    | lemon | 6.40 |
    | mango | 15.60 |
    | melon | 8.20 |
    | orange | 11.30 |
    | xbababa | 3.60 |
    | xbabay | 2.60 |
    | xxtt | 11.60 |
    | xxxx | 3.60 |
    ±----------±--------+
    16 rows in set (0.00 sec)

在對多列進行排序的時候,首先排序的第一列必須有相同的列值,纔會對第二列進行排序。如果第一列數據中所有的值都是唯一的,將不再對第二列進行排序。

在排序的時候(ASC)爲默認的排序方式。

先按f_price降序排序,再將f_name字段升序排序

如果要對多列進行降序排序,必須要在每一列的列名後面加DESC關鍵字

分組查詢

GROUP BY 通常與集合函數一起使用:MAX(),MIN(),COUNT(),SUM(),AVG()
mysql> SELECT s_id,COUNT(*) AS Total FROM fruits GROUP BY s_id;
±-----±------+
| s_id | Total |
±-----±------+
| 101 | 3 |
| 102 | 3 |
| 103 | 2 |
| 104 | 2 |
| 105 | 3 |
| 106 | 1 |
| 107 | 2 |
±-----±------+
7 rows in set (0.00 sec)

顯示每個分組的各個字段

1
2
3
4
5
6
7
8
9
10
11
12
13
mysql> SELECT s_id,GROUP_CONCAT(f_name) AS Names FROM fruits GROUP BY s_id;
+------+------------------------+
| s_id | Names |
+------+------------------------+
| 101 | apple,blckberry,cherry |
| 102 | orange,banana,grape |
| 103 | apricot,cocount |
| 104 | berry,lemon |
| 105 | melon,xbabay,xxtt |
| 106 | mango |
| 107 | xxxx,xbababa |
+------+------------------------+
7 rows in set (0.00 sec)
  • 使用HAVIING過濾分組

顯示水果種類大於1的分組信息
mysql> SELECT s_id,GROUP_CONCAT(f_name) AS Names FROM fruits GROUP BY s_id HAVING COUNT(f_name)>1;
±-----±-----------------------+
| s_id | Names |
±-----±-----------------------+
| 101 | apple,blckberry,cherry |
| 102 | orange,banana,grape |
| 103 | apricot,cocount |
| 104 | berry,lemon |
| 105 | melon,xbabay,xxtt |
| 107 | xxxx,xbababa |
±-----±-----------------------+
6 rows in set (0.00 sec)

HAVING和WHERE 過濾數據的區別

HAVING在數據分組之後進行過濾,WHERE分組之前用來選擇記錄,WHERE排除的記錄將不包含在分組中

使用WITH ROLLUP,在所有查詢出的分組記錄之後增加一條記錄,該記錄計算查詢出的所有記錄的總和,統計記錄數量。
mysql> SELECT s_id,COUNT(*) AS TOTAL FROM fruits GROUP BY s_id WITH ROLLUP;
±-----±------+
| s_id | TOTAL |
±-----±------+
| 101 | 3 |
| 102 | 3 |
| 103 | 2 |
| 104 | 2 |
| 105 | 3 |
| 106 | 1 |
| 107 | 2 |
| NULL | 16 |
±-----±------+
8 rows in set (0.00 sec)

多字段分組,分組層次從左至右,先按第一個字段分組,然後在第一個字段值相同的記錄中,再根據第2個字段的值進行分組。
mysql> SELECT * FROM fruits GROUP BY s_id,f_name;
±-----±-----±----------±--------+
| f_id | s_id | f_name | f_price |
±-----±-----±----------±--------+
| a1 | 101 | apple | 5.20 |
| b1 | 101 | blckberry | 10.20 |
| c0 | 101 | cherry | 3.20 |
| t1 | 102 | banana | 10.30 |
| t2 | 102 | grape | 5.30 |
| bs1 | 102 | orange | 11.30 |
| a2 | 103 | apricot | 2.20 |
| o2 | 103 | cocount | 9.20 |
| b2 | 104 | berry | 7.60 |
| l2 | 104 | lemon | 6.40 |
| bs2 | 105 | melon | 8.20 |
| m2 | 105 | xbabay | 2.60 |
| m3 | 105 | xxtt | 11.60 |
| m1 | 106 | mango | 15.60 |
| t4 | 107 | xbababa | 3.60 |
| b5 | 107 | xxxx | 3.60 |
±-----±-----±----------±--------+
16 rows in set (0.01 sec)

2019年3月31日更新

GROUP BY和ORDER BY進行分組排序

表結構
Database changed
mysql> CREATE TABLE orderitems
-> (
-> o_num int NOT NULL,
-> o_item int NOT NULL,
-> f_id char(10) NOT NULL,
-> quantity int NOT NULL,
-> item_price decimal(8,2) NOT NULL,
-> PRIMARY KEY (o_num,o_item));
Query OK, 0 rows affected (0.01 sec)

mysql> INSERT INTO orderitems(o_num,o_item,f_id,quantity,item_price)
-> VALUES(30001,1,'a1',10,5.2),
-> (30001,2,'b2',3,7.6),
-> (30001,3,'bs1',5,11.2),
-> (30001,4,'bs2',15,9.2),
-> (30002,1,'b3',2,20.0),
-> (30003,1,'c0',100,10),
-> (30004,1,'o2',50,2.50),
-> (30005,1,'c0',5,10),
-> (30005,2,'b1',10,8.99),
-> (30005,3,'a2',10,2.2),
-> (30005,4,'m1',5,14.99);
Query OK, 11 rows affected (0.01 sec)
Records: 11 Duplicates: 0 Warnings: 0

查詢訂單價格大於100的訂單號和總訂單價格
mysql> SELECT o_num,SUM(quantityitem_price) AS order_total FROM orderitems GROUP BY o_num HAVING SUM(quantityitem_price)>=100;
±------±------------+
| o_num | order_total |
±------±------------+
| 30001 | 268.80 |
| 30003 | 1000.00 |
| 30004 | 125.00 |
| 30005 | 236.85 |
±------±------------+

對order_total進行排序
mysql> SELECT o_num,SUM(quantityitem_price) AS order_total FROM orderitems GROUP BY o_num HAVING SUM(quantityitem_price)>=100 ORDER BY order_total;
±------±------------+
| o_num | order_total |
±------±------------+
| 30004 | 125.00 |
| 30005 | 236.85 |
| 30001 | 268.80 |
| 30003 | 1000.00 |
±------±------------+
4 rows in set (0.00 sec)

ROLLUP和ORDER BY是互斥的

使用LIMIT限制查詢結果的數量

1
LIMIT [位置偏移量,] 行數

第一條記錄的位置偏移量是0

查前4行
mysql> SELECT * FROM fruits LIMIT 4;
±-----±-----±----------±--------+
| f_id | s_id | f_name | f_price |
±-----±-----±----------±--------+
| a1 | 101 | apple | 5.20 |
| a2 | 103 | apricot | 2.20 |
| b1 | 101 | blckberry | 10.20 |
| b2 | 104 | berry | 7.60 |
±-----±-----±----------±--------+
4 rows in set (0.00 sec)

從第5個記錄開始,行數長度爲3的記錄
mysql> SELECT * FROM fruits LIMIT 4,3;
±-----±-----±-------±--------+
| f_id | s_id | f_name | f_price |
±-----±-----±-------±--------+
| b5 | 107 | xxxx | 3.60 |
| bs1 | 102 | orange | 11.30 |
| bs2 | 105 | melon | 8.20 |
±-----±-----±-------±--------+
3 rows in set (0.00 sec)

MySQL聚合函數

|函數|作用
|------
|AVG()|返回某列的平均值
|COUNT()|返回某列的行數
|MAX()|返回某列的最大值
|MIN()|返回某列的最小值
|SUM()|返回某列值的和

【計算某一字段總的行數,忽略空值的行】查詢customers表中有電子郵箱的顧客的總數
mysql> SELECT COUNT(c_email) AS email_num FROM customers;
±----------+
| email_num |
±----------+
| 3 |
±----------+
1 row in set (0.00 sec)

【COUNT(*)不忽略記錄中的空值行】

SUM計算每個分組中記錄的總和,忽略空值行
mysql> SELECT o_num,SUM(quantity) AS items_total FROM orderitems GROUP BY o_num;
±------±------------+
| o_num | items_total |
±------±------------+
| 30001 | 33 |
| 30002 | 2 |
| 30003 | 100 |
| 30004 | 50 |
| 30005 | 30 |
±------±------------+
5 rows in set (0.00 sec)

AVG()求指定列數據的平均值
mysql> SELECT AVG(f_price) AS avg_price FROM fruits WHERE s_id =103;
±----------+
| avg_price |
±----------+
| 5.700000 |
±----------+
1 row in set (0.00 sec)

如果多列求多個平均值,則每一列都要用AVG函數

查找不同供應商提供的價格最高的水果值
mysql> SELECT s_id,MAX(f_price) AS max_price FROM fruits GROUP BY s_id;
±-----±----------+
| s_id | max_price |
±-----±----------+
| 101 | 10.20 |
| 102 | 11.30 |
| 103 | 9.20 |
| 104 | 7.60 |
| 105 | 11.60 |
| 106 | 15.60 |
| 107 | 3.60 |
±-----±----------+
7 rows in set (0.00 sec)

MAX可以返回字符的最大值,按ASCII碼值,先比較第一個字母,如果相等,繼續比較下一個,一直到兩個字符不相等或者字符結束爲止。

連接查詢

當兩個或多個表中存在相同意義的字段時,便可以通過這些字段對不同的表進行連接查詢

內連接(INNER JOIN)使用比較運算符進行表間某些列數據的比較操作,並列出這些表中與連接條件相匹配的數據行,組合成新的記錄。

倆個表都具有相同字段s_id
mysql> DESC fruits;
±--------±-------------±-----±----±--------±------+
| Field | Type | Null | Key | Default | Extra |
±--------±-------------±-----±----±--------±------+
| f_id | char(10) | NO | PRI | NULL | |
| s_id | int(11) | NO | | NULL | |
| f_name | char(255) | NO | | NULL | |
| f_price | decimal(8,2) | NO | | NULL | |
±--------±-------------±-----±----±--------±------+
4 rows in set (0.06 sec)

mysql> DESC suppliers;
±-------±---------±-----±----±--------±---------------+
| Field | Type | Null | Key | Default | Extra |
±-------±---------±-----±----±--------±---------------+
| s_id | int(11) | NO | PRI | NULL | auto_increment |
| s_name | char(50) | NO | | NULL | |
| s_city | char(50) | YES | | NULL | |
| s_zip | char(10) | YES | | NULL | |
| s_call | char(50) | NO | | NULL | |
±-------±---------±-----±----±--------±---------------+
5 rows in set (0.00 sec)

從fruits表中查f_name、f_price字段,從suppliers表中查詢s_id、s_name
mysql> SELECT suppliers.s_id,s_name,f_name,f_price FROM fruits,suppliers WHERE fruits.s_id = suppliers.s_id;
±-----±---------------±----------±--------+
| s_id | s_name | f_name | f_price |
±-----±---------------±----------±--------+
| 101 | FastFruit Inc. | apple | 5.20 |
| 103 | ACME | apricot | 2.20 |
| 101 | FastFruit Inc. | blckberry | 10.20 |
| 104 | FNK Inc. | berry | 7.60 |
| 107 | DK Inc | xxxx | 3.60 |
| 102 | LT Supplies | orange | 11.30 |
| 105 | Good Set. | melon | 8.20 |
| 101 | FastFruit Inc. | cherry | 3.20 |
| 104 | FNK Inc. | lemon | 6.40 |
| 106 | Just Eat Ours | mango | 15.60 |
| 105 | Good Set. | xbabay | 2.60 |
| 105 | Good Set. | xxtt | 11.60 |
| 103 | ACME | cocount | 9.20 |
| 102 | LT Supplies | banana | 10.30 |
| 102 | LT Supplies | grape | 5.30 |
| 107 | DK Inc | xbababa | 3.60 |
±-----±---------------±----------±--------+
16 rows in set (0.01 sec)

使用內連接進行查詢
mysql> SELECT suppliers.s_id,s_name,f_name,f_price FROM fruits,suppliers WHERE fruits.s_id = suppliers.s_id;
±-----±---------------±----------±--------+
| s_id | s_name | f_name | f_price |
±-----±---------------±----------±--------+
| 101 | FastFruit Inc. | apple | 5.20 |
| 103 | ACME | apricot | 2.20 |
| 101 | FastFruit Inc. | blckberry | 10.20 |
| 104 | FNK Inc. | berry | 7.60 |
| 107 | DK Inc | xxxx | 3.60 |
| 102 | LT Supplies | orange | 11.30 |
| 105 | Good Set. | melon | 8.20 |
| 101 | FastFruit Inc. | cherry | 3.20 |
| 104 | FNK Inc. | lemon | 6.40 |
| 106 | Just Eat Ours | mango | 15.60 |
| 105 | Good Set. | xbabay | 2.60 |
| 105 | Good Set. | xxtt | 11.60 |
| 103 | ACME | cocount | 9.20 |
| 102 | LT Supplies | banana | 10.30 |
| 102 | LT Supplies | grape | 5.30 |
| 107 | DK Inc | xbababa | 3.60 |
±-----±---------------±----------±--------+
16 rows in set (0.01 sec)

在一個連接查詢中,涉及到的兩個表都是同一個表,這種查詢稱爲自連接查詢。

查詢供應f_id = ‘a1’的水果供應商提供的其他水果種類
mysql> SELECT f1.f_id,f1.f_name FROM fruits AS f1,fruits AS f2 WHERE f1.s_id = f2.s_id AND f2.f_id = 'a1';
±-----±----------+
| f_id | f_name |
±-----±----------+
| a1 | apple |
| b1 | blckberry |
| c0 | cherry |
±-----±----------+
3 rows in set (0.01 sec)

外連接

LEFT JOIN(左連接):返回包括左表中的所有記錄和右表中連接字段相等的記錄

RIGHT JOIN(右連接):返回包括右表中的所有記錄和左表中連接字段相等的記錄

左連接的結果包括LEFT OUTER子句中指定的左表的所有行,而不僅僅是連接列所匹配的行。如果左表的某行在右表中沒有匹配行,則在相關聯的結果行中,右表中的所有選擇列表列均爲空值。

查詢所有客戶,包括沒有訂單的客戶
mysql> SELECT customers.c_id,orders.o_num FROM customers LEFT OUTER JOIN orders ON customers.c_id = orders.c_id;
±------±------+
| c_id | o_num |
±------±------+
| 10001 | 30001 |
| 10003 | 30002 |
| 10004 | 30003 |
| 10001 | 30005 |
| 10002 | NULL |
±------±------+
5 rows in set (0.00 sec)

查詢所有訂單,包括沒有客戶的訂單
mysql> SELECT customers.c_id,orders.o_num FROM customers RIGHT OUTER JOIN orders ON customers.c_id = orders.c_id;
±------±------+
| c_id | o_num |
±------±------+
| 10001 | 30001 |
| 10003 | 30002 |
| 10004 | 30003 |
| NULL | 30004 |
| 10001 | 30005 |
±------±------+
5 rows in set (0.00 sec)

複合條件連接查詢

通過添加過濾條件,限制查詢結果

查詢customers表中ID爲10001的客戶的訂單信息
mysql> SELECT customers.c_id,orders.o_num FROM customers INNER JOIN orders ON customers.c_id = orders.c_id AND customers.c_id =10001;
±------±------+
| c_id | o_num |
±------±------+
| 10001 | 30001 |
| 10001 | 30005 |
±------±------+
2 rows in set (0.00 sec)

子查詢

子查詢結果作爲外層另一個查詢的過濾條件。

常用操作符ANY(SOME)\ALL\IN\EXISTS

ANY\SOME表示滿足其中任一條件,只要滿足內層子查詢的任何一個比較條件,就返回一個結果作爲外層查詢的條件。

ANY關鍵字接在一個比較操作符後面,表示若與子查詢返回的任何值比較爲TRUE,則返回TRUE
mysql> INSERT INTO tb11 values(1),(5),(13),(27);
Query OK, 4 rows affected (0.00 sec)
Records: 4 Duplicates: 0 Warnings: 0

mysql> INSERT INTO tb12 values(6),(14),(11),(20);
Query OK, 4 rows affected (0.00 sec)
Records: 4 Duplicates: 0 Warnings: 0

mysql> SELECT num1 FROM tb11 WHERE num1 > ANY (SELECT num2 FROM tb12);
±-----+
| num1 |
±-----+
| 13 |
| 27 |
±-----+
2 rows in set (0.00 sec)

ALL需要同時滿足所有內層查詢的條件
mysql> SELECT num1 FROM tb11 WHERE num1 > ALL (SELECT num2 FROM tb12);
±-----+
| num1 |
±-----+
| 27 |
±-----+
1 row in set (0.00 sec)

EXISTS關鍵字後面參數是任意一個子查詢,系統對子查詢進行運算以判斷它是否返回行,如果至少返回一行,則結果爲true,此時外層查詢語句將進行查詢。

查詢suppliers表中是否存在s_id=107的供應商,如果存在,則查詢fruits表中的記錄:
mysql> SELECT * FROM fruits WHERE EXISTS (SELECT s_name FROM suppliers WHERE s_id = 107);
±-----±-----±----------±--------+
| f_id | s_id | f_name | f_price |
±-----±-----±----------±--------+
| a1 | 101 | apple | 5.20 |
| a2 | 103 | apricot | 2.20 |
| b1 | 101 | blckberry | 10.20 |
| b2 | 104 | berry | 7.60 |
| b5 | 107 | xxxx | 3.60 |
| bs1 | 102 | orange | 11.30 |
| bs2 | 105 | melon | 8.20 |
| c0 | 101 | cherry | 3.20 |
| l2 | 104 | lemon | 6.40 |
| m1 | 106 | mango | 15.60 |
| m2 | 105 | xbabay | 2.60 |
| m3 | 105 | xxtt | 11.60 |
| o2 | 103 | cocount | 9.20 |
| t1 | 102 | banana | 10.30 |
| t2 | 102 | grape | 5.30 |
| t4 | 107 | xbababa | 3.60 |
±-----±-----±----------±--------+
16 rows in set (0.00 sec)

查詢suppliers表中是否存在s_id = 107的供應商,如果存在,則查詢fruits表中的f_price大於10.20的記錄
mysql> SELECT * FROM fruits WHERE f_price>10.20 AND EXISTS (SELECT s_name FROM suppliers WHERE s_id = 107);
±-----±-----±-------±--------+
| f_id | s_id | f_name | f_price |
±-----±-----±-------±--------+
| bs1 | 102 | orange | 11.30 |
| m1 | 106 | mango | 15.60 |
| m3 | 105 | xxtt | 11.60 |
| t1 | 102 | banana | 10.30 |
±-----±-----±-------±--------+
4 rows in set (0.01 sec)

EXISTS和NOT EXISTS的結果只取決於是否會返回行,而不取決於這些行的內容。

帶IN關鍵字的子查詢

在orderitems表中查詢f_id爲c0的訂單號,並根據訂單號查詢具有訂單號的客戶c_id
mysql> SELECT c_id FROM orders WHERE o_num IN (SELECT o_num FROM orderitems WHERE f_id = 'c0');
±------+
| c_id |
±------+
| 10004 |
| 10001 |
±------+
2 rows in set (0.00 sec)

UNION關鍵字可以給出多條SELECT語句,並將它們的結果組合成單個結果集,合併時,兩個表對應的列數和數據類型必須相同。

SELECT語句之間使用UNION (執行的時候刪除重複記錄)和 UNION ALL(不刪除重複行也不對結果進行重複排序)分隔
mysql> SELECT s_id,f_name,f_price FROM fruits WHERE f_price < 9.0 UNION ALL SELECT s_id,f_name,f_price FROM fruits WHERE s_id IN (101,103);
±-----±----------±--------+
| s_id | f_name | f_price |
±-----±----------±--------+
| 101 | apple | 5.20 |
| 103 | apricot | 2.20 |
| 104 | berry | 7.60 |
| 107 | xxxx | 3.60 |
| 105 | melon | 8.20 |
| 101 | cherry | 3.20 |
| 104 | lemon | 6.40 |
| 105 | xbabay | 2.60 |
| 102 | grape | 5.30 |
| 107 | xbababa | 3.60 |
| 101 | apple | 5.20 |
| 103 | apricot | 2.20 |
| 101 | blckberry | 10.20 |
| 101 | cherry | 3.20 |
| 103 | cocount | 9.20 |
±-----±----------±--------+
15 rows in set (0.06 sec)

確定查詢結果中不會有重複數據或者不需要去掉重複數據的時候,使用UNION ALL以提高查詢效率

分別取別名,並進行連接查詢
mysql> SELECT c.c_id,o.o_num FROM customers AS c LEFT OUTER JOIN orders AS o ON c.c_id=o.c_id;
±------±------+
| c_id | o_num |
±------±------+
| 10001 | 30001 |
| 10003 | 30002 |
| 10004 | 30003 |
| 10001 | 30005 |
| 10002 | NULL |
±------±------+
5 rows in set (0.01 sec)

表、字段別名
mysql> SELECT CONCAT(TRIM(s_name),'(',TRIM(s_city),')') AS suppliers_title FROM suppliers ORDER BY s_name;
±------------------------+
| suppliers_title |
±------------------------+
| ACME(Shanghai) |
| DK Inc(Zhengzhou) |
| FastFruit Inc.(Tianjin) |
| FNK Inc.(Zhongshan) |
| Good Set.(Taiyuang) |
| Just Eat Ours(Beijing) |
| LT Supplies(Chongqing) |
±------------------------+
7 rows in set (0.01 sec)

|選項|說明|例子
|------
||匹配文本的開始字符|‘b’匹配以字母b開頭的字符串
|st|匹配文本的結束字符|‘st’匹配以st結尾的字符串
|.|匹配任何單個字符|‘b.t’匹配任何b和t之間有一個字符
||匹配零個或多個在它前面的字符|‘fn’匹配字符n前面有任意個字符f
|+|匹配前面的字符一次或多次|‘ba+’匹配以b開頭後面緊跟至少有一個a
|<字符串>|匹配包含指定字符串的文本|‘fa’
|[字符集合]|匹配字符集合中的任意一個字符|‘[xz]’匹配x或者z
|[]|匹配不在括號中的任何字符|‘[abc]’匹配任何不包含a,b,c的字符串
|字符串{n,}|匹配前面的字符串至少n次|b{2}匹配2個或更多的b
|字符串{n,m}|匹配前面的字符串至少n次,至多m次。如果n爲0,此參數爲可選參數|b[2,4]匹配最少2個,最多4個b

查詢f_name字段以字母’y’結尾的記錄
mysql> SELECT * FROM fruits WHERE f_name REGEXP 'y$';
±-----±-----±----------±--------+
| f_id | s_id | f_name | f_price |
±-----±-----±----------±--------+
| b1 | 101 | blckberry | 10.20 |
| b2 | 104 | berry | 7.60 |
| c0 | 101 | cherry | 3.20 |
| m2 | 105 | xbabay | 2.60 |
±-----±-----±----------±--------+
4 rows in set (0.00 sec)

綜合案例
mysql> desc dept;
±-----------±-------------±-----±----±--------±---------------+
| Field | Type | Null | Key | Default | Extra |
±-----------±-------------±-----±----±--------±---------------+
| d_no | int(11) | NO | PRI | NULL | auto_increment |
| d_name | varchar(50) | YES | | NULL | |
| d_location | varchar(100) | YES | | NULL | |
±-----------±-------------±-----±----±--------±---------------+
3 rows in set (0.00 sec)
mysql> desc employee;
±---------±-------------±-----±----±--------±------+
| Field | Type | Null | Key | Default | Extra |
±---------±-------------±-----±----±--------±------+
| e_no | int(11) | NO | PRI | NULL | |
| e_name | varchar(100) | NO | | NULL | |
| e_gender | char(2) | NO | | NULL | |
| dept_no | int(11) | NO | MUL | NULL | |
| e_job | varchar(100) | NO | | NULL | |
| e_salary | smallint(6) | NO | | NULL | |
| hireDate | date | YES | | NULL | |
±---------±-------------±-----±----±--------±------+
7 rows in set (0.00 sec)

1.計算所有女員工f的年齡

查找出所有的女員工
mysql> desc employee;
±---------±-------------±-----±----±--------±------+
| Field | Type | Null | Key | Default | Extra |
±---------±-------------±-----±----±--------±------+
| e_no | int(11) | NO | PRI | NULL | |
| e_name | varchar(100) | NO | | NULL | |
| e_gender | char(2) | NO | | NULL | |
| dept_no | int(11) | NO | MUL | NULL | |
| e_job | varchar(100) | NO | | NULL | |
| e_salary | smallint(6) | NO | | NULL | |
| hireDate | date | YES | | NULL | |
±---------±-------------±-----±----±--------±------+
7 rows in set (0.00 sec)

使用LIMIT查詢從第3條記錄開始到第6條記錄
mysql> desc employee;
±---------±-------------±-----±----±--------±------+
| Field | Type | Null | Key | Default | Extra |
±---------±-------------±-----±----±--------±------+
| e_no | int(11) | NO | PRI | NULL | |
| e_name | varchar(100) | NO | | NULL | |
| e_gender | char(2) | NO | | NULL | |
| dept_no | int(11) | NO | MUL | NULL | |
| e_job | varchar(100) | NO | | NULL | |
| e_salary | smallint(6) | NO | | NULL | |
| hireDate | date | YES | | NULL | |
±---------±-------------±-----±----±--------±------+
7 rows in set (0.00 sec)

查詢銷售人員(SALSEMAN)的最低工資
mysql> INSERT INTO employee
-> VALUES (1001,'SMITH','m',20,'CLERK',800,'2005-11-12'),
-> (1002,'ALLEN','f',30,'SALESMAN',1600,'2003-05-12'),
-> (1003,'WARD','f',30,'SALESMAN',1250,'2003-05-12'),
-> (1004,'JONES','m',20,'MANAGER',2975,'1998-05-18'),
-> (1005,'MARTIN','m',30,'SALESMAN',1250,'2001-06-12'),
-> (1006,'BLAKE','f',30,'MANAGER',2850,'1997-02-15'),
-> (1007,'CLARK','m',10,'MANAGER',2450,'2002-09-12'),
-> (1008,'SCOTT','m',20,'ANALYST',3000,'2003-05-12'),
-> (1009,'KING','f',10,'PRESIDENT',5000,'1995-01-01'),
-> (1010,'TURNER','f',30,'SALESMAN',1500,'1997-10-12'),
-> (1011,'ADAMS','m',20,'CLERK',1100,'1999-10-05'),
-> (1012,'JAMES','m',30,'CLERK',950,'2008-06-15');
Query OK, 12 rows affected (0.01 sec)
Records: 12 Duplicates: 0 Warnings: 0

mysql> SELECT MIN(e_salary) FROM employee WHERE e_job = 'SALESMAN';
+---------------+
| MIN(e_salary) |
+---------------+
| 1250 |
+---------------+
1 row in set (0.00 sec)

查詢名字以字母N或者S結尾的記錄
mysql> SELECT * FROM employee WHERE e_name REGEXP '[N,S]$';
±-----±-------±---------±--------±---------±---------±-----------+
| e_no | e_name | e_gender | dept_no | e_job | e_salary | hireDate |
±-----±-------±---------±--------±---------±---------±-----------+
| 1002 | ALLEN | f | 30 | SALESMAN | 1600 | 2003-05-12 |
| 1004 | JONES | m | 20 | MANAGER | 2975 | 1998-05-18 |
| 1005 | MARTIN | m | 30 | SALESMAN | 1250 | 2001-06-12 |
| 1011 | ADAMS | m | 20 | CLERK | 1100 | 1999-10-05 |
| 1012 | JAMES | m | 30 | CLERK | 950 | 2008-06-15 |
±-----±-------±---------±--------±---------±---------±-----------+
5 rows in set (0.00 sec)

查詢在BeiJing工作的員工的姓名和職務

mysql> SELECT e_name,e_job FROM employee WHERE dept_no IN (SELECT d_no FROM dept WHERE d_location = 'BeiJing');
+--------+---------+
| e_name | e_job |
+--------+---------+
| SMITH | CLERK |
| JONES | MANAGER |
| SCOTT | ANALYST |
| ADAMS | CLERK |
+--------+---------+
4 rows in set (0.00 sec)

使用左連接方式查詢employee表和dept表
mysql> SELECT * FROM employee LEFT OUTER JOIN dept ON dept.d_no = employee.dept_no;
±-----±-------±---------±--------±----------±---------±-----------±-----±-----------±-----------+
| e_no | e_name | e_gender | dept_no | e_job | e_salary | hireDate | d_no | d_name | d_location |
±-----±-------±---------±--------±----------±---------±-----------±-----±-----------±-----------+
| 1007 | CLARK | m | 10 | MANAGER | 2450 | 2002-09-12 | 10 | ACCOUNTING | ShangHai |
| 1009 | KING | f | 10 | PRESIDENT | 5000 | 1995-01-01 | 10 | ACCOUNTING | ShangHai |
| 1001 | SMITH | m | 20 | CLERK | 800 | 2005-11-12 | 20 | RESEARCH | BeiJing |
| 1004 | JONES | m | 20 | MANAGER | 2975 | 1998-05-18 | 20 | RESEARCH | BeiJing |
| 1008 | SCOTT | m | 20 | ANALYST | 3000 | 2003-05-12 | 20 | RESEARCH | BeiJing |
| 1011 | ADAMS | m | 20 | CLERK | 1100 | 1999-10-05 | 20 | RESEARCH | BeiJing |
| 1002 | ALLEN | f | 30 | SALESMAN | 1600 | 2003-05-12 | 30 | SALES | ShenZhen |
| 1003 | WARD | f | 30 | SALESMAN | 1250 | 2003-05-12 | 30 | SALES | ShenZhen |
| 1005 | MARTIN | m | 30 | SALESMAN | 1250 | 2001-06-12 | 30 | SALES | ShenZhen |
| 1006 | BLAKE | f | 30 | MANAGER | 2850 | 1997-02-15 | 30 | SALES | ShenZhen |
| 1010 | TURNER | f | 30 | SALESMAN | 1500 | 1997-10-12 | 30 | SALES | ShenZhen |
| 1012 | JAMES | m | 30 | CLERK | 950 | 2008-06-15 | 30 | SALES | ShenZhen |
±-----±-------±---------±--------±----------±---------±-----------±-----±-----------±-----------+
12 rows in set (0.00 sec)

查詢所有2001-2005年入職的員工的信息,查詢部門編號爲20和30的員工信息並使用UNION合併兩個查詢結果
mysql> SELECT * FROM employee WHERE YEAR(hireDate) BETWEEN '2001' and '2005' UNION ALL SELECT * FROM employee WHERE dept_no IN (20,30) ;
±-----±-------±---------±--------±---------±---------±-----------+
| e_no | e_name | e_gender | dept_no | e_job | e_salary | hireDate |
±-----±-------±---------±--------±---------±---------±-----------+
| 1001 | SMITH | m | 20 | CLERK | 800 | 2005-11-12 |
| 1002 | ALLEN | f | 30 | SALESMAN | 1600 | 2003-05-12 |
| 1003 | WARD | f | 30 | SALESMAN | 1250 | 2003-05-12 |
| 1005 | MARTIN | m | 30 | SALESMAN | 1250 | 2001-06-12 |
| 1007 | CLARK | m | 10 | MANAGER | 2450 | 2002-09-12 |
| 1008 | SCOTT | m | 20 | ANALYST | 3000 | 2003-05-12 |
| 1001 | SMITH | m | 20 | CLERK | 800 | 2005-11-12 |
| 1002 | ALLEN | f | 30 | SALESMAN | 1600 | 2003-05-12 |
| 1003 | WARD | f | 30 | SALESMAN | 1250 | 2003-05-12 |
| 1004 | JONES | m | 20 | MANAGER | 2975 | 1998-05-18 |
| 1005 | MARTIN | m | 30 | SALESMAN | 1250 | 2001-06-12 |
| 1006 | BLAKE | f | 30 | MANAGER | 2850 | 1997-02-15 |
| 1008 | SCOTT | m | 20 | ANALYST | 3000 | 2003-05-12 |
| 1010 | TURNER | f | 30 | SALESMAN | 1500 | 1997-10-12 |
| 1011 | ADAMS | m | 20 | CLERK | 1100 | 1999-10-05 |
| 1012 | JAMES | m | 30 | CLERK | 950 | 2008-06-15 |
±-----±-------±---------±--------±---------±---------±-----------+

使用LIKE 查詢員工姓名中包含字母a的記錄
mysql> SELECT * FROM employee WHERE e_name LIKE '%a%';
±-----±-------±---------±--------±---------±---------±-----------+
| e_no | e_name | e_gender | dept_no | e_job | e_salary | hireDate |
±-----±-------±---------±--------±---------±---------±-----------+
| 1002 | ALLEN | f | 30 | SALESMAN | 1600 | 2003-05-12 |
| 1003 | WARD | f | 30 | SALESMAN | 1250 | 2003-05-12 |
| 1005 | MARTIN | m | 30 | SALESMAN | 1250 | 2001-06-12 |
| 1006 | BLAKE | f | 30 | MANAGER | 2850 | 1997-02-15 |
| 1007 | CLARK | m | 10 | MANAGER | 2450 | 2002-09-12 |
| 1011 | ADAMS | m | 20 | CLERK | 1100 | 1999-10-05 |
| 1012 | JAMES | m | 30 | CLERK | 950 | 2008-06-15 |
±-----±-------±---------±--------±---------±---------±-----------+

使用REGEXP查詢員工姓名中包含T、C或者M3個字母中任意一個的記錄
mysql> SELECT e_name FROM employee WHERE e_name REGEXP '[TCM]' ;
±-------+
| e_name |
±-------+
| SMITH |
| MARTIN |
| CLARK |
| SCOTT |
| TURNER |
| ADAMS |
| JAMES |
±-------+
7 rows in set (0.00 sec)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章