超越基本 SELECT,本文整理 MySQL 進階查詢模式:精確/模糊/範圍查詢、時間處理、聚合函數、多重分組、HAVING、UNION、內/外/交叉/自我連接、子查詢 (IN/EXISTS)、排序技巧與常見陷阱。
IN 列舉:SELECT * FROM students WHERE native IN ('湖南','四川');BETWEEN ... AND:SELECT * FROM students WHERE age BETWEEN 20 AND 30;= 精確:SELECT * FROM students WHERE name = '李山';% 任意長度:name LIKE '李%' (以李開頭)、'%李%' (含李)、'%李' (以李結尾)_ 單一字元:'_李%' (第二字為李)[] 字元集合 (MySQL 不支援,屬 T-SQL):MySQL 用 REGEXP 或 IN 替代。
SELECT * FROM students WHERE birth >= '1980-01-01' AND birth <= '1980-12-31';
-- 或
SELECT * FROM students WHERE YEAR(birth) = 1980;
COUNT(*) 總筆數AVG(mark) 平均分MAX(mark)/MIN(mark) 最高/最低分
-- 單欄位分組
SELECT gender, COUNT(*) FROM students GROUP BY gender;
-- 多重分組:年級、系所、性別
SELECT grade, mno, gender, COUNT(*) FROM students GROUP BY grade, mno, gender;
-- HAVING 過濾分組結果:不及格超過 1 門的學生
SELECT sno, COUNT(*) FROM grades WHERE mark < 60 GROUP BY sno HAVING COUNT(*) > 1;
SELECT * FROM students WHERE name LIKE '張%'
UNION [ALL]
SELECT * FROM students WHERE name LIKE '李%';
UNION 去重,UNION ALL 保留重複 (效能較好)。
SELECT g.sno, s.name, c.coursename
FROM grades g
JOIN students s ON g.sno = s.sno
JOIN courses c ON g.cno = c.cno;
SELECT c.cno, MAX(c.coursename), COUNT(g.sno)
FROM courses c
LEFT JOIN grades g ON c.cno = g.cno
GROUP BY c.cno;
LEFT JOIN UNION RIGHT JOIN 模擬
SELECT c1.cno, c1.coursename, c1.pno, c2.coursename
FROM courses c1, courses c2 WHERE c1.pno = c2.cno;
CROSS JOIN
-- IN 子查詢:查詢李山的同鄉
SELECT * FROM students WHERE native IN (SELECT native FROM students WHERE name = '李山');
-- EXISTS 相關子查詢:選修 B2 課程的學生
SELECT * FROM students WHERE EXISTS (
SELECT * FROM grades WHERE grades.sno = students.sno AND cno = 'B2'
);
ORDER BY 3:依 SELECT 清單第 3 個運算式排序 (如 ORDER BY AVG(mark))。ASC (預設) / DESC。WHERE mark IS NULL (不可用 = NULL)
-- 錯誤:未選 B2 的學生 (會列出選了其他課的同學)
SELECT * FROM students, grades WHERE students.sno = grades.sno AND grades.cno <> 'B2';
-- 正確:NOT EXISTS
SELECT * FROM students WHERE NOT EXISTS (
SELECT * FROM grades WHERE grades.sno = students.sno AND cno = 'B2'
);
SELECT * FROM students WHERE NOT EXISTS (
SELECT * FROM courses WHERE NOT EXISTS (
SELECT * FROM grades WHERE grades.sno = students.sno AND grades.cno = courses.cno
)
);
熟練運用子查詢、多種連接類型、集合運算與分組過濾,能以聲明式 SQL 解決複雜業務問題。注意 MySQL 版本對特定語法 (如 CTE、窗函數) 的支援度,並在大資料量時配合索引與 EXPLAIN 優化。