SELECT title, price FROM course WHERE price > 100;
-- 3 行:Java 基础入门 199 / Java 面向对象进阶 299 / MySQL 性能优化实战 399
SELECT title, status FROM course WHERE status = 'published';
-- 5 行
SELECT title, created_at FROM course
WHERE created_at BETWEEN '2026-06-01' AND '2026-06-10';
-- 只有 4 行!course 5 是 06-10 10:00 创建的,被「00:00:00」边界吃掉了
-- 正确的半开区间写法(左闭右开):
SELECT title, created_at FROM course
WHERE created_at >= '2026-06-10 00:00:00'
AND created_at < '2026-06-11 00:00:00';
步骤 5:LIKE 模糊匹配
SELECT title FROM course WHERE title LIKE '%Java%'; -- 2 行(包含 Java)
SELECT slug FROM course WHERE slug LIKE 'java-%'; -- 2 行(前缀匹配)
SELECT slug FROM course WHERE slug LIKE 'java-_'; -- 1 行:java-oop(_ 占 1 个字符)
% 匹配任意长度,_ 匹配单个字符
LIKE 'java-%' 前缀确定,可以走索引;LIKE '%Java%' 前缀不确定,走不了(第 8 课用 EXPLAIN 验证)
步骤 6:IS NULL —— 判空唯一正确姿势
SELECT id, student_id, lesson_id, completed_at
FROM study_record
WHERE completed_at IS NULL;
-- 1 行:id=12,大鹏学了但没完成的那条
SELECT COUNT(*) FROM study_record WHERE completed_at IS NOT NULL; -- 16
WHERE completed_at = NULL 永远返回空集,因为 NULL 和任何值的比较都是 UNKNOWN。判空只能用 IS NULL / IS NOT NULL。
步骤 7:ORDER BY 排序
SELECT title, price FROM course
WHERE status = 'published'
ORDER BY price DESC; -- 降序:399 → 199
-- 多列排序:先按 category 升序,同分类内按 price 降序
SELECT category, title, price FROM course ORDER BY category ASC, price DESC;
-- ASC 是默认值,可省略
SELECT name, balance FROM student ORDER BY balance; -- 0 → 500
NULL 在排序里的位置(MySQL 规则):升序时 NULL 排最前面,降序时排最后面。想强制控制用 ORDER BY completed_at IS NULL, completed_at(先把 NULL 沉底)。
步骤 8:LIMIT / OFFSET 分页
SELECT id, name FROM student ORDER BY id LIMIT 3; -- 第 1 页:1,2,3
SELECT id, name FROM student ORDER BY id LIMIT 3 OFFSET 3; -- 第 2 页:4,5,6
-- LIMIT 3 = LIMIT 3 OFFSET 3 的简写
通用公式:第 n 页、每页 pageSize 条 → LIMIT pageSize OFFSET (n-1)*pageSize。前提是必须先 ORDER BY 一个稳定列(通常是主键或带索引的时间列),否则翻页会出现重复和漏行。