<表示式> [NOT] IN <子查詢>
語法說明如下。<表示式>
:用於指定表示式。當表示式與子查詢返回的結果集中的某個值相等時,返回 TRUE,否則返回 FALSE;若使用關鍵字 NOT,則返回的值正好相反。<子查詢>
:用於指定子查詢。這裡的子查詢只能返回一列資料。對於比較複雜的查詢要求,可以使用 SELECT 語句實現子查詢的多層巢狀。
<表示式> {= | < | > | >= | <= | <=> | < > | != }
{ ALL | SOME | ANY} <子查詢>
<子查詢>
:用於指定子查詢。<表示式>
:用於指定要進行比較的表示式。ALL
、SOME
和 ANY
:可選項。用於指定對比較運算的限制。其中,關鍵字 ALL 用於指定表示式需要與子查詢結果集中的每個值都進行比較,當表示式與每個值都滿足比較關係時,會返回 TRUE,否則返回 FALSE;關鍵字 SOME 和 ANY 是同義詞,表示表示式只要與子查詢結果集中的某個值滿足比較關係,就返回 TRUE,否則返回 FALSE。EXIST <子查詢>
若子查詢的結果集不為空,則返回 TRUE;否則返回 FALSE。mysql> SELECT name FROM tb_students_info -> WHERE dept_id IN -> (SELECT dept_id -> FROM tb_departments -> WHERE dept_type= 'A' ); +-------+ | name | +-------+ | Dany | | Henry | | Jane | | Jim | | John | +-------+ 5 rows in set (0.01 sec)上述查詢過程可以分步執行,首先內層子查詢查出 tb_departments 表中符合條件的學院 ID,單獨執行內查詢,查詢結果如下所示。
mysql> SELECT dept_id -> FROM tb_departments -> WHERE dept_type='A'; +---------+ | dept_id | +---------+ | 1 | | 2 | +---------+ 2 rows in set (0.00 sec)可以看到,符合條件的 dept_id 列的值有兩個:1 和 2。然後執行外層查詢,在 tb_students_info 表中查詢 dept_id 等於 1 或 2 的學生的名字。巢狀子查詢語句還可以寫為如下形式,可以實現相同的效果。
mysql> SELECT name FROM tb_students_info -> WHERE dept_id IN(1,2); +-------+ | name | +-------+ | Dany | | Henry | | Jane | | Jim | | John | +-------+ 5 rows in set (0.03 sec)上例說明在處理 SELECT 語句時,MySQL 實際上執行了兩個操作過程,即先執行內層子查詢,再執行外層查詢,內層子查詢的結果作為外部查詢的比較條件。
mysql> SELECT name FROM tb_students_info -> WHERE dept_id NOT IN -> (SELECT dept_id -> FROM tb_departments -> WHERE dept_type='A'); +--------+ | name | +--------+ | Green | | Lily | | Susan | | Thomas | | Tom | +--------+ 5 rows in set (0.04 sec)
【範例 3】在 tb_departments 表中查詢 dept_name 等於“Computer”的學院 id,然後在 tb_students_info 表中查詢所有該學院的學生的姓名,輸入的 SQL 語句和執行過程如下所示。提示:子查詢的功能也可以通過連線查詢完成,但是子查詢使得 MySQL 程式碼更容易閱讀和編寫。
mysql> SELECT name FROM tb_students_info -> WHERE dept_id = -> (SELECT dept_id -> FROM tb_departments -> WHERE dept_name='Computer'); +------+ | name | +------+ | Dany | | Jane | | Jim | +------+ 3 rows in set (0.00 sec)【範例 4】在 tb_departments 表中查詢 dept_name 不等於“Computer”的學院 id,然後在 tb_students_info 表中查詢所有該學院的學生的姓名,輸入的 SQL 語句和執行過程如下所示。
mysql> SELECT name FROM tb_students_info -> WHERE dept_id <> -> (SELECT dept_id -> FROM tb_departments -> WHERE dept_name='Computer'); +--------+ | name | +--------+ | Green | | Henry | | John | | Lily | | Susan | | Thomas | | Tom | +--------+ 7 rows in set (0.00 sec)【範例 5】查詢 tb_departments 表中是否存在 dept_id=1 的供應商,如果存在,就查詢 tb_students_info 表中的記錄,輸入的 SQL 語句和執行結果如下所示。
mysql> SELECT * FROM tb_students_info -> WHERE EXISTS -> (SELECT dept_name -> FROM tb_departments -> WHERE dept_id=1); +----+--------+---------+------+------+--------+------------+ | id | name | dept_id | age | sex | height | login_date | +----+--------+---------+------+------+--------+------------+ | 1 | Dany | 1 | 25 | F | 160 | 2015-09-10 | | 2 | Green | 3 | 23 | F | 158 | 2016-10-22 | | 3 | Henry | 2 | 23 | M | 185 | 2015-05-31 | | 4 | Jane | 1 | 22 | F | 162 | 2016-12-20 | | 5 | Jim | 1 | 24 | M | 175 | 2016-01-15 | | 6 | John | 2 | 21 | M | 172 | 2015-11-11 | | 7 | Lily | 6 | 22 | F | 165 | 2016-02-26 | | 8 | Susan | 4 | 23 | F | 170 | 2015-10-01 | | 9 | Thomas | 3 | 22 | M | 178 | 2016-06-07 | | 10 | Tom | 4 | 23 | M | 165 | 2016-08-05 | +----+--------+---------+------+------+--------+------------+ 10 rows in set (0.00 sec)由結果可以看到,內層查詢結果表明 tb_departments 表中存在 dept_id=1 的記錄,因此 EXSTS 表示式返回 TRUE,外層查詢語句接收 TRUE 之後對表 tb_students_info 進行查詢,返回所有的記錄。
mysql> SELECT * FROM tb_students_info -> WHERE EXISTS -> (SELECT dept_name -> FROM tb_departments -> WHERE dept_id=7); Empty set (0.00 sec)