爲了演示的需要,首先創建數據表suppliers,SQL語句如下:
CREATE TABLE suppliers
(
s_id int NOT NULL AUTO_INCREMENT,
s_name char(50) NOT NULL,
s_city char(50) NULL,
s_zip char(10) NULL,
s_call CHAR(50) NOT NULL,
PRIMARY KEY (s_id)
) ;
插入需要演示的數據,SQL語句如下:
INSERT INTO suppliers(s_id, s_name,s_city, s_zip, s_call)
VALUES(101,'FastFruit Inc.','Tianjin','300000','48075'),
(102,'LT Supplies','Chongqing','400000','44333'),
(103,'ACME','Shanghai','200000','90046'),
(104,'FNK Inc.','Zhongshan','528437','11111'),
(105,'Good Set','Taiyuang','030000', '22222'),
(106,'Just Eat Ours','Beijing','010', '45678'),
(107,'DK Inc.','Zhengzhou','450000', '33332');
【例46】在fruits表和suppliers表之間使用內連接查詢。
查詢之前,查看兩個表的結構:
DESC fruits;
DESC suppliers;
由結果可以看到,fruits表和suppliers表中都有相同數據類型的字段s_id,兩個表通過s_id字段建立聯繫。接下來從fruits表中查詢f_name、f_price字段,從suppliers表中查詢s_id、s_name,SQL語句如下:
SELECT suppliers.s_id, s_name,f_name, f_price
FROM fruits ,suppliers
WHERE fruits.s_id = suppliers.s_id;
【例47】在fruits表和suppliers表之間,使用INNER JOIN語法進行內連接查詢,SQL語句如下:
SELECT suppliers.s_id, s_name,f_name, f_price
FROM fruits INNER JOIN suppliers
ON fruits.s_id = suppliers.s_id;
【例48】查詢供應f_id= ‘a1’的水果供應商提供的其他水果種類,SQL語句如下:
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';
1.LEFT JOIN左連接
左連接的結果包括LEFT OUTER子句中指定的左表的所有行,而不僅僅是連接列所匹配的行。如果左表的某行在右表中沒有匹配行,則在相關聯的結果行中,右表的所有選擇列表列均爲空值。
首先創建表orders,SQL語句如下:
CREATE TABLE orders
(
o_num int NOT NULL AUTO_INCREMENT,
o_date datetime NOT NULL,
c_id int NOT NULL,
PRIMARY KEY (o_num)
) ;
插入需要演示的數據,SQL語句如下:
INSERT INTO orders(o_num, o_date, c_id)
VALUES(30001, '2008-09-01', 10001),
(30002, '2008-09-12', 10003),
(30003, '2008-09-30', 10004),
(30004, '2008-10-03', 10005),
(30005, '2008-10-08', 10001);
【例49】在customers表和orders表中,查詢所有客戶,包括沒有訂單的客戶,SQL語句如下:
SELECT customers.c_id, orders.o_num
FROM customers LEFT OUTER JOIN orders
ON customers.c_id = orders.c_id;
2.RIGHT JOIN右連接
右連接是左連接的反向連接,將返回右表的所有行。如果右表的某行在左表中沒有匹配行,左表將返回空值。
【例50】在customers表和orders表中,查詢所有訂單,包括沒有客戶的訂單,SQL語句如下:
SELECT customers.c_id, orders.o_num
FROM customers RIGHT OUTER JOIN orders
ON customers.c_id = orders.c_id;
【例51】在customers表和orders表中,使用INNER JOIN語法查詢customers表中ID爲10001的客戶的訂單信息,SQL語句如下:
SELECT customers.c_id, orders.o_num
FROM customers INNER JOIN orders
ON customers.c_id = orders.c_id AND customers.c_id = 10001;
【例52】在fruits表和suppliers表之間,使用INNER JOIN語法進行內連接查詢,並對查詢結果排序,SQL語句如下:
SELECT suppliers.s_id, s_name,f_name, f_price
FROM fruits INNER JOIN suppliers
ON fruits.s_id = suppliers.s_id
ORDER BY fruits.s_id;
帶ANY、SOME關鍵字的子查詢
ANY和SOME關鍵字是同義詞,表示滿足其中任一條件,它們允許創建一個表達式對子查詢的返回值列表進行比較,只要滿足內層子查詢中的任何一個比較條件,就返回一個結果作爲外層查詢的條件。
下面定義兩個表tb1和tb2:
CREATE table tbl1 ( num1 INT NOT NULL);
CREATE table tbl2 ( num2 INT NOT NULL);
分別向兩個表中插入數據:
INSERT INTO tbl1 values(1), (5), (13), (27);
INSERT INTO tbl2 values(6), (14), (11), (20);
ANY關鍵字接在一個比較操作符的後面,表示若與子查詢返回的任何值比較爲TRUE,則返回TRUE。
【例53】返回tbl2表的所有num2列,然後將tbl1中的num1的值與之進行比較,只要大於num2的任何1個值,即爲符合查詢條件的結果。
SELECT num1 FROM tbl1
WHERE num1 > ANY (SELECT num2 FROM tbl2);
【例54】返回tbl1表中比tbl2表num2 列所有值都大的值,SQL語句如下:
SELECT num1 FROM tbl1
WHERE num1 > ALL (SELECT num2 FROM tbl2);
【例55】查詢suppliers表中是否存在s_id=107的供應商,如果存在,則查詢fruits表中的記錄,SQL語句如下:
SELECT * FROM fruits
WHERE EXISTS
(SELECT s_name FROM suppliers WHERE s_id = 107);
【例56】查詢suppliers表中是否存在s_id=107的供應商,如果存在,則查詢fruits表中的f_price大於10.20的記錄,SQL語句如下:
SELECT * FROM fruits
WHERE f_price>10.20 AND EXISTS
(SELECT s_name FROM suppliers WHERE s_id = 107);
【例57】查詢suppliers表中是否存在s_id=107的供應商,如果不存在則查詢fruits表中的記錄,SQL語句如下:
SELECT * FROM fruits
WHERE NOT EXISTS
(SELECT s_name FROM suppliers WHERE s_id = 107);
【例58】在orderitems表中查詢f_id爲c0的訂單號,並根據訂單號查詢具有訂單號的客戶c_id,SQL語句如下:
SELECT c_id FROM orders WHERE o_num IN
(SELECT o_num FROM orderitems WHERE f_id = 'c0');
SELECT o_num FROM orderitems WHERE f_id = 'c0';
可以看到,符合條件的o_num列的值有兩個:30003和30005,然後執行外層查詢,在orders表中查詢訂單號等於30003或30005的客戶c_id。嵌套子查詢語句還可以寫爲如下形式,實現相同的效果:
SELECT c_id FROM orders WHERE o_num IN (30003, 30005);
【例59】與前一個例子類似,但是在SELECT語句中使用NOT IN關鍵字,SQL語句如下:
SELECT c_id FROM orders WHERE o_num NOT IN
(SELECT o_num FROM orderitems WHERE f_id = 'c0');
SELECT * FROM orders;
【例60】在suppliers表中查詢s_city等於“Tianjin”的供應商s_id,然後在fruits表中查詢所有該供應商提供的水果的種類,SQL語句如下:
SELECT s_id, f_name FROM fruits
WHERE s_id =
(SELECT s1.s_id FROM suppliers AS s1 WHERE s1.s_city = 'Tianjin');
【例61】在suppliers表中查詢s_city等於“Tianjin”的供應商s_id,然後在fruits表中查詢所有非該供應商提供的水果的種類,SQL語句如下:
SELECT s_id, f_name FROM fruits
WHERE s_id <>
(SELECT s1.s_id FROM suppliers AS s1 WHERE s1.s_city = 'Tianjin');
【例62】查詢所有價格小於9的水果的信息,查詢s_id等於101和103所有的水果的信息,使用UNION連接查詢結果,SQL語句如下:
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);
如前所述,UNION將多個SELECT語句的結果組合成一個結果集合。可以分開查看每個SELECT語句的結果:
SELECT s_id, f_name, f_price
FROM fruits
WHERE f_price < 9.0;
+------+-----------+---------+
| 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 |
+------+-----------+---------+
10 rows in set (0.00 sec)
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 |
| 101 | blackberry| 10.20 |
| 101 | cherry | 3.20 |
| 103 | coconut | 9.20 |
+------+------------+---------+
【例63】查詢所有價格小於9的水果的信息,查詢s_id等於101和103的所有水果的信息,使用UNION ALL連接查詢結果,SQL語句如下:
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);
【例64】爲orders表取別名o,查詢30001訂單的下單日期,SQL語句如下:
SELECT * FROM orders AS o
WHERE o.o_num = 30001;
在這裏orders AS o代碼表示爲orders表取別名爲o,指定過濾條件時直接使用o代替orders,查詢結果如下:
+-------+---------------------+-------+
| o_num | o_date | c_id |
+-------+---------------------+-------+
| 30001 | 2008-09-01 00:00:00 | 10001 |
+-------+---------------------+-------+
【例65】爲customers和orders表分別取別名,並進行連接查詢,SQL語句如下:
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 |
| 10001 | 30005 |
| 10002 | NULL |
| 10003 | 30002 |
| 10004 | 30003 |
+-------+-------+
由結果看到,MySQL可以同時爲多個表取別名,而且表別名可以放在不同的位置,如WHERE子句、SELECT列表、ON子句以及ORDER BY子句等。
在前面介紹內連接查詢時指出自連接是一種特殊的內連接,在連接查詢中的兩個表都是同一個表,其查詢語句如下:
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 | blackberry |
| c0 | cherry |
+------+------------+
【例66】查詢fruits表,爲f_name取別名fruit_name,f_price取別名fruit_price,爲fruits表取別名f1,查詢表中f_price < 8的水果的名稱,SQL語句如下:
SELECT f1.f_name AS fruit_name, f1.f_price AS fruit_price
FROM fruits AS f1
WHERE f1.f_price < 8;
【例67】查詢suppliers表中字段s_name和s_city,使用CONCAT函數連接這兩個字段值,並取列別名爲suppliers_title。
如果沒有對連接後的值取別名,其顯示列名稱將會不夠直觀,SQL語句如下:
SELECT CONCAT(TRIM(s_name) , ' (', TRIM(s_city), ')')
FROM suppliers
ORDER BY s_name;
+--------------------------------------------------------------+
| CONCAT(TRIM(s_name) , ' (', TRIM(s_city), ')') |
+--------------------------------------------------------------+
| ACME (Shanghai) |
| DK Inc. (Qingdao) |
| FastFruit Inc. (Tianjin) |
| FNK Inc. (Zhongshan) |
| Good Set (Taiyuan) |
| Just Eat Ours (Beijing) |
| LT Supplies (Chongqing) |
+---------------------------------------------------------------+
由結果可以看到,顯示結果的列名稱爲SELECT子句後面的計算字段,實際上計算之後的列是沒有名字的,這樣的結果讓人很不容易理解,如果爲字段取一個別名,將會使結果清晰,SQL語句如下,
SELECT CONCAT(TRIM(s_name) , ' (', TRIM(s_city), ')')
AS suppliers_title
FROM suppliers
ORDER BY s_name;
+------------------------------+
| suppliers_title |
+------------------------------+
| ACME (Shanghai) |
| DK Inc. (Qingdao) |
| FastFruit Inc. (Tianjin) |
| FNK Inc. (Zhongshan) |
| Good Set (Taiyuan) |
| Just Eat Ours (Beijing) |
| LT Supplies (Chongqing)|
+------------------------------+
【例68】在fruits表中,查詢f_name字段以字母’b’開頭的記錄,SQL語句如下:
SELECT * FROM fruits WHERE f_name REGEXP '^b';
+------+------+-----------------+------------+
| f_id | s_id | f_name | f_price |
+------+------+-----------------+-------------+
| b1 | 101 | blackberry | 10.20 |
| b2 | 104 | berry | 7.60 |
| t1 | 102 | banana | 10.30 |
+------+----------+---------------+-----------+
fruits表中有3條記錄的f_name字段值是以字母b開頭,返回結果有3條記錄。
【例69】在fruits表中,查詢f_name字段以“be”開頭的記錄,SQL語句如下:
SELECT * FROM fruits WHERE f_name REGEXP '^be';
+------+------+--------+---------+
| f_id | s_id | f_name | f_price |
+------+------+--------+---------+
| b2 | 104 | berry | 7.60 |
+------+------+--------+---------+
只有berry是以“be”開頭,所以查詢結果中只有1條記錄。
超全面的測試IT技術課程,0元立即加入學習!有需要的朋友戳:
騰訊課堂測試技術學習地址
歡迎轉載,但未經作者同意請保留此段聲明,並在文章頁面明顯位置給出原文鏈接。