首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

MySQL IN 操作符兩大用法:子查詢與值列表

     編輯:MySQL 綜合教學

MySQL IN 操作符兩大用法:子查詢與值列表

IN 操作符用於判斷某值是否在指定集合中,集合來源可為子查詢結果集或顯式值列表。

場景表結構

-- 學生表
s(sno, sname, sex, age, dept)

-- 課程表
c(cno, cname, tname)

-- 選課表
sc(sno, cno, grade)

用法一:IN 後接子查詢(動態集合)

需求:將「物理」課程不及格(<60分)的學生成績設為 0。

UPDATE sc
SET grade = 0
WHERE sc.cno IN (SELECT cno FROM c WHERE c.cname = '物理')
  AND sc.grade < 60;

解析:

  1. 子查詢 SELECT cno FROM c WHERE c.cname = '物理' 返回課號集合(如 'C01', 'C02')。
  2. 外層 WHERE sc.cno IN (...) 匹配這些課號的選課記錄。
  3. 再配合 sc.grade < 60 過濾不及格記錄並更新。

優勢:集合隨資料動態變化,無需硬編碼值。

用法二:IN 後接顯式值列表(靜態集合)

需求:查詢姓名為 'aaa'、'bbb'、'ccc' 的學生資料。

SELECT * FROM s WHERE sname IN ('aaa', 'bbb', 'ccc');

值列表不限於字串,數值、日期皆可:

SELECT * FROM sc WHERE grade IN (60, 70, 80, 90, 100);
SELECT * FROM s WHERE age IN (18, 19, 20);

效能與最佳實踐

場景建議
值列表較小(< 100)且固定直接用 IN (val1, val2...),MySQL 內部優化為二分搜尋。
值列表大或頻變用臨時表或子查詢,避免 SQL 過長解析開銷。
子查詢返回大量行考慮改用 EXISTS 或 JOIN,避免 IN 子查詢在舊版本(<5.6)效能差。
欄位有索引IN 可走索引範圍掃描(range),效能佳。

常見錯誤

-- 錯誤:混合型別(數字與字串)
SELECT * FROM t WHERE id IN (1, 2, 'a');

-- 正確:統一型別
SELECT * FROM t WHERE id IN ('1', '2', 'a');

MySQL 會嘗試將所有值轉換為相同型別比較,混合型別導致隱式轉換結果難以預期。

NOT IN 注意事項

NOT IN 若子查詢結果含 NULL,整個判斷永遠為 NULL(非 TRUE),導致無資料返回。解決:

-- 避免 NULL
SELECT * FROM s WHERE sno NOT IN (SELECT sno FROM sc WHERE grade > 80 AND sno IS NOT NULL);

-- 或改用 NOT EXISTS(推薦)
SELECT * FROM s WHERE NOT EXISTS (SELECT 1 FROM sc WHERE sc.sno = s.sno AND grade > 80);
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved