下面講講關于MySQL子查詢Subquery,文字的奧妙在于貼近主題相關。所以,閑話就不談了,我們直接看下文吧,相信看完MySQL子查詢Subquery這篇文章你一定會有所受益。
成都創(chuàng)新互聯(lián)公司是一家企業(yè)級云計算解決方案提供商,超15年IDC數(shù)據(jù)中心運營經(jīng)驗。主營GPU顯卡服務器,站群服務器,成都服務器托管,海外高防服務器,成都機柜租用,動態(tài)撥號VPS,海外云手機,海外云服務器,海外服務器租用托管等。
子查詢,是指在SQL語句中內(nèi)嵌了一個SELECT查詢,該SELECT稱為內(nèi)層查詢,包含SELECT的SQL稱為外層查詢.其按照內(nèi)層查詢是否依賴于外層查詢,可以分為獨立子查詢和相關子查詢.
為了演示方便,有測試表tb1和tb2,數(shù)據(jù)如下:
mysql> SELECT * FROM tb1;
+------+
| col1 |
+------+
| 3 |
| 9 |
+------+
2 rows in set (0.00 sec)
mysql> SELECT * FROM tb2;
+------+
| col1 |
+------+
| 2 |
| 3 |
| 8 |
+------+
3 rows in set (0.00 sec)
獨立子查詢,是指內(nèi)層和外層查詢沒有關聯(lián),不用進行聯(lián)合查詢.和其相關的有三組關鍵字: ANY/ IN/ SOME, ALL和EXISTS.
ANY/ IN/ SOME的語法是:
operand comparison_operator ANY (subquery)
operand IN (subquery)
operand comparison_operator SOME (subquery)
a. ANY關鍵字的含義是,對于在子查詢返回的列中的任一值,如果表達式結果為TRUE的話,則返回TRUE.
對于如下SQL,表tb1包含(3, 9), tb2包含(2, 3, 8),表達式結果為TRUE.
mysql> SELECT col1 FROM tb1 WHERE col1> ANY (SELECT col1 FROM tb2);
+------+
| col1 |
+------+
| 3 |
| 9 |
+------+
2 rows in set (0.00 sec)
b.在子查詢中, = ANY的別名是IN,下面兩個SQL返回是相同的.
mysql>SELECT col1 FROM tb1WHERE col1 = ANY (SELECT col1 FROM tb2);
+------+
| col1 |
+------+
| 3 |
+------+
1 row in set (0.00 sec)
mysql>SELECT col1 FROM tb1WHERE col1 IN (SELECT col1 FROM tb2);
+------+
| col1 |
+------+
| 3 |
+------+
1 row in set (0.00 sec)
c. ANY的別名是SOME,下面兩個SQL返回是相同的.
mysql>SELECT col1 FROM tb1WHERE col1 <> ANY (SELECT col1 FROM tb2);
+------+
| col1 |
+------+
| 3 |
| 9 |
+------+
2 rows in set (0.00 sec)
mysql>SELECT col1 FROM tb1WHERE col1 <> SOME (SELECT col1 FROM tb2);
+------+
| col1 |
+------+
| 3 |
| 9 |
+------+
2 rows in set (0.00 sec)
ALL的語法是:
operand comparison_operator ALL (subquery)
a. ALL關鍵字的含義是,對于在子查詢返回的列中的所有值,如果表達式結果為TRUE的話,則返回TRUE.
mysql>SELECT col1 FROM tb1WHERE col1 > ALL (SELECT col1 FROM tb2);
+------+
| col1 |
+------+
| 9 |
+------+
1 row in set (0.00 sec)
b. <> ALL的別名是NOT IN,下面兩個SQL返回是相同的.
mysql>SELECT col1 FROM tb1 WHERE col1 <> ALL (SELECT col1 FROM tb2);
+------+
| col1 |
+------+
| 9 |
+------+
1 row in set (0.00 sec)
mysql> SELECT col1 FROM tb1WHERE col1 NOT IN (SELECT col1 FROM tb2);
+------+
| col1 |
+------+
| 9 |
+------+
1 row in set (0.00 sec)
最后一組關鍵字是EXISTS.
a.EXISTS的含義是,若子查詢返回非空集,則EXISTS為TRUE, NOTEXISTS為FALSE.下面的SQL只是為了便于理解EXISTS,一般不這樣用.
mysql>SELECT col1 FROM tb1 WHERE EXISTS (SELECT * FROMtb2);
+------+
| col1 |
+------+
| 3 |
| 9 |
+------+
rows in set (0.00 sec)
b.如下EXISTS子查詢比較接近實際情況,獲取表tb1和tb2中相同的記錄.可以看到其內(nèi)層關聯(lián)了外層表,這也就是下面說的相關子查詢.
mysql>SELECTcol1 FROM tb1 WHERE EXISTS (SELECT * FROM tb2 WHERE tb2.col1 = tb1.col1);
+------+
| col1 |
+------+
| 3 |
+------+
1 row in set (0.00 sec)
相關子查詢,是指內(nèi)層查詢需要和外層查詢的表相關聯(lián),進行聯(lián)合查詢.在上面已經(jīng)看到了相關子查詢的例子,仔細體會下其和獨立子查詢語法上的差異.
另外,如上面的SELECT col1 FROM tb1 WHEREEXISTS(SELECT * FROM tb2WHERE tb2.col1 = tb1.col1),是和再上面的SELECT col1 FROM tb1 WHERE col1 IN (SELECT col1 FROM tb2)等價的,即可將IN的獨立子查詢和EXISTS的相關子查詢相互改寫,那么兩者有什么不同呢 …
在表tb2中加入一條記錄(NULL),其數(shù)據(jù)如下, tb1的不變:
mysql> SELECT * FROM tb2;
+------+
| col1 |
+------+
| 2 |
| 3 |
| 8 |
| NULL |
+------+
4 rows in set (0.00 sec)
找出在表tb1,不在tb2中的記錄,目測結果應為9,但返回卻為空.
mysql> SELECT * FROM tb1 WHERE col1 NOTIN (SELECT col1 FROM tb2);
Empty set (0.00 sec)
為什么呢,測試如下,原來在有NULL值的情況下, NOT IN只返回NOT TRUE和NULL,即FALSE.就是在NULL的情況下, NOT IN永遠不會返回結果.
mysql> SELECT 'a' NOT IN ('a', 'b',NULL);
+-----------------------------+
| 'a' NOT IN ('a', 'b', NULL) |
+-----------------------------+
| 0 |
+-----------------------------+
1 row in set (0.00 sec)
mysql> SELECT 'c' NOT IN ('a', 'b',NULL);
+-----------------------------+
| 'c' NOT IN ('a', 'b', NULL) |
+-----------------------------+
| NULL |
+-----------------------------+
1 row in set (0.00 sec)
若想NOT IN返回結果,要先過濾掉NULL值,這里也說明了不建議把數(shù)據(jù)存為NULL的原因.
mysql> SELECT * FROM tb1 WHERE col1 NOTIN (SELECT col1 FROM tb2 WHERE col1 IS NOT NULL);
+------+
| col1 |
+------+
| 9 |
+------+
1 row in set (0.00 sec)
使用EXISTS來寫的話,由于其是相關子查詢,不用特殊考慮NULL的情況.
mysql> SELECT * FROM tb1 WHERE NOTEXISTS (SELECT col1 FROM tb2 WHERE tb2.col1 = tb1.col1);
+------+
| col1 |
+------+
| 9 |
+------+
1 row in set (0.00 sec)
對于子查詢的性能優(yōu)化,以及改寫為JOIN等,稍后會進行整理,感興趣可關注訂閱號”數(shù)據(jù)庫最佳實踐”(DBBestPractice).
對于以上MySQL子查詢Subquery相關內(nèi)容,大家還有什么不明白的地方嗎?或者想要了解更多相關,可以繼續(xù)關注我們的行業(yè)資訊板塊。
當前題目:MySQL子查詢Subquery語法介紹
文章位置:http://jinyejixie.com/article20/gdhoco.html
成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供動態(tài)網(wǎng)站、網(wǎng)站建設、企業(yè)建站、靜態(tài)網(wǎng)站、營銷型網(wǎng)站建設、網(wǎng)站排名
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉載內(nèi)容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)