简介:这份PDF笔记整理自B站Mosh老师的SQL三小时入门课程,面向零基础或希望系统梳理SQL语法的开发者与数据库初学者,帮助读者在短时间内建立可实际套用的查询知识框架。内容覆盖SQL基础概念、SELECT子句、WHERE条件筛选、AND/OR/NOT逻辑操作符,以及IN、BETWEEN、LIKE、REGEXP等常用操作符的语法与用法,并延伸至IS NULL、ORDER BY、LIMIT、内外连接、USING与交叉连接、UNION及数据插入等主题,按知识点分节编排,便于对照视频逐段复习与速查。资源包共1个PDF文件,大小约2.43MB,轻量易存,适合打印或放在手边当作速查手册。目前已有979人学习,说明其在入门群体中具备一定参考价值,适合作为课程配套笔记与日常查询语法的随手参考。
1. 三小时 SQL 速通地图:先看清这门语言到底由哪几块拼成
很多人学 SQL 的路径是反的:一上来就背SELECT * FROM 表,背完发现换个场景就写不出来。真正有效的顺序是先看清地图——SQL 在入门阶段其实只有四块拼图:查什么(SELECT)、从哪查(FROM 与 JOIN)、筛什么(WHERE 系列操作符)、怎么排和截(ORDER BY 与 LIMIT)。这份三小时课程笔记的价值,就在于它把四块拼图按「单表查询 → 条件过滤 → 多表连接 → 数据写入」的顺序串成了一条线,而不是散落成一堆语法卡片。
它适合两类人:一是刚接触关系型数据库、需要一张能照着走的地图的人;二是学过一阵但知识点是碎的、想重新梳理一遍的人。下面按模块拆开,每块都落到「重点在哪、容易错在哪」,最后给一份可以照着自查的复习清单。
2. 单表查询四件套:SELECT、WHERE、ORDER BY、LIMIT 的复习重点
单表查询是整个 SQL 的地基,地基不稳,后面 JOIN 一定翻车。这一块的核心不是记住语法,而是理解一条语句的执行顺序和你书写顺序并不一致:你写的是 SELECT → FROM → WHERE → ORDER BY → LIMIT,数据库实际先定位表、再过滤行、再排序、最后截取。理解这一点,很多「为什么别名在 WHERE 里用不了」的疑惑会自动消失。
2.1 SELECT 子句:表达式、别名与去重
SELECT 不只是列名列表,它支持表达式计算和别名。课程里给的例子是给积分打折扣:
-- 用表达式算出折扣系数,并起一个可读的别名 SELECT (points * 10 + 20) AS discount_factor FROM customers;这里有两个复习点。第一是运算优先级:括号 → 乘除 → 加减,和普通算术一致,复杂表达式建议强制加括号,别赌记忆。第二是AS别名,别名让结果集可读,也方便后续在 ORDER BY 里引用(注意 WHERE 阶段别名通常还不可用,这是执行顺序决定的)。
去重靠DISTINCT:
-- 只取不重复的州,常用于快速摸清某列有哪些取值 SELECT DISTINCT state FROM customers;DISTINCT作用于整行组合,写SELECT DISTINCT state, city去重的是「州+城市」这个组合,不是单独某一列——这是新手最常见的误解之一。
2.2 WHERE 与比较、逻辑操作符:过滤条件的骨架
WHERE 决定哪些行进入结果集,比较操作符有>、>=、<、<=、=、<>和!=(后两个都表示不等于)。逻辑操作符三个:AND要求两边都真,OR只要一边真,NOT取反。
-- AND:两个条件同时满足 SELECT * FROM customers WHERE birthdate > '1990-01-01' AND points > 1000; -- NOT:对整个条件取反,括号不能省 SELECT * FROM customers WHERE NOT (birthdate > '1990-01-01');重点在NOT那条:NOT后面必须用括号把完整条件包住,否则取反范围会和你以为的不一样。另一个高频坑是AND与OR混用时的优先级——AND先于OR结合,a OR b AND c实际是a OR (b AND c),想要别的语义必须自己加括号。这条血泪经验值得单独记一笔。
2.3 范围与集合:IN、BETWEEN 的边界语义
IN判断值是否落在某个列表里,BETWEEN判断是否落在闭区间内:
-- 州属于这三个之一 SELECT * FROM customers WHERE state IN ('VA', 'NY', 'CA'); -- 积分在 100 到 200 之间,两端都包含 SELECT * FROM customers WHERE points BETWEEN 100 AND 200;BETWEEN是闭区间,包含 100 和 200 本身,这一点和某些语言里的半开区间习惯不同,考试和实际查询都爱在这里设陷阱。IN的列表里如果混入NULL,匹配行为会变得反直觉,入门阶段先记住:列表里别放NULL。
2.4 模式匹配:LIKE 与 REGEXP 的分工
LIKE用两个通配符:%匹配任意数量字符,_匹配恰好一个字符。
-- 名字以 b 开头 SELECT * FROM customers WHERE first_name LIKE 'b%';REGEXP则直接上正则,表达力更强:
-- 以 a 开头 WHERE first_name REGEXP '^a'; -- 以 ey 或 on 结尾 WHERE first_name REGEXP 'ey$|on$'; -- 以 my 开头或包含 se WHERE first_name REGEXP '^my|se'; -- 包含 b,且 b 后面紧跟 r 或 u WHERE first_name REGEXP 'b[ru]';正则里的关键符号要背熟:^开头、$结尾、|逻辑或、[abc]匹配其中任一单字符、[a-d]匹配区间内任一字符。复习时最容易混的是LIKE的%和正则的.*——两者语义相近但语法完全不同,写混了不会报错,只会静默返回错误结果,属于典型的「玄学 bug」来源。
2.5 空值判断:IS NULL 不能写成 = NULL
-- 找出没有电话号码的客户 SELECT * FROM customers WHERE phone IS NULL;NULL表示未知,任何与NULL的比较结果都是未知而非真,所以phone = NULL永远筛不出东西。判断空值只能用IS NULL或IS NOT NULL。这条几乎是 SQL 入门必考、实战必踩的坑,单独列进易错清单毫不为过。
2.6 排序与截取:ORDER BY 与 LIMIT 的组合
-- 先按州升序,同州内按名字降序 SELECT * FROM customers ORDER BY state, first_name DESC; -- 只取前 3 条 SELECT * FROM customers LIMIT 3; -- 跳过 6 条,再取 3 条 SELECT * FROM customers LIMIT 6, 3;ORDER BY默认升序,多列排序时每个列可以单独指定升降序。LIMIT 6, 3的语义是「偏移 6 行、取 3 行」,第一个数字是跳过量不是起始行号,这个偏移语义在分页场景里天天用,记反了分页就会错位一页。
3. 多表连接:JOIN 家族与 UNION 的取舍逻辑
单表玩熟之后,真实业务数据几乎都分散在多张表里,连接(JOIN)就是把这些表按关联键拼起来。这一块的复习目标很明确:分清内连接、外连接、交叉连接各自保留哪些行,以及 UNION 和 JOIN 是两件完全不同的事。
3.1 内连接与外连接:保留行的差别是全部
内连接只保留两表都能匹配上的行:
-- 只返回有订单的客户 SELECT * FROM customers c JOIN orders o ON c.customer_id = o.customer_id;左外连接则保留左表全部行,右表匹配不上就补空:
-- 返回所有客户,没下过单的订单字段为 NULL SELECT * FROM customers c LEFT JOIN orders o ON c.customer_id = o.customer_id;复习重点在于「保留谁」。JOIN(即内连接)会丢掉没有订单的客户,LEFT JOIN会保留他们。判断该用哪个,问自己一句:没有匹配记录的主体,要不要出现在结果里?要,就用外连接。这是业务查询里最容易选错的地方,选错不会报错,只会悄悄少数据。
3.2 USING 子句:同名列的简化写法
当两张表的关联列名字完全相同时,可以用USING替代ON:
-- 两表都有 customer_id 列,可简写 SELECT * FROM customers c JOIN orders o USING (customer_id);它等价于ON c.customer_id = o.customer_id,但要求列名严格一致。复习时记住它的适用边界:列名不同就只能老老实实写ON,别硬套。
3.3 交叉连接:笛卡尔积不是 bug 是特性
-- 每种颜色配每种尺寸,得到全部组合 SELECT * FROM colors CROSS JOIN sizes;交叉连接返回两表的笛卡尔积,行数是两表行数之积。它本身有正当用途(生成组合、构造测试数据),但忘记写连接条件的内连接会退化成笛卡尔积,结果行数爆炸——这是排查「查询突然变慢、结果多出几百倍」时的第一嫌疑点。
3.4 UNION:纵向拼接结果集
JOIN 是横向拼列,UNION 是纵向拼行:
-- 把客户和潜在客户合成一张名单 SELECT name, address FROM customers UNION SELECT name, address FROM clients;UNION要求两侧列数相同、类型兼容,并且默认去重;想保留重复要用UNION ALL。复习时把「JOIN 拼列、UNION 拼行」这句话刻进脑子,两者混用是概念性错误,不是语法错误。
4. 数据写入与语句规范:INSERT 与那些不报错却出错的细节
查询之外,写入是另一条主线。入门阶段主要是INSERT,但真正值得复习的是围绕语句的一圈「规范细节」,它们不写不报错,写错了却很难查。
4.1 INSERT 的两种形态:单行与多行
-- 插入单条,未提供的列走默认值 INSERT INTO customers(first_name, phone, points) VALUES ('Mosh', NULL, DEFAULT); -- 一次插入多条,逗号分隔 INSERT INTO customers(first_name, phone, points) VALUES ('Mosh', NULL, DEFAULT), ('Bob', '1234', 10);两个复习点:一是显式列出列名,别依赖表结构顺序,表加列后隐式插入会错位;二是DEFAULT关键字让某列走默认值,比手填一个「看起来对」的值安全。
4.2 语句规范:分号、大小写与注释
课程明确提到:SQL 本身不区分大小写,但在 MySQL 里每条语句必须以分号结尾。大小写不敏感意味着select和SELECT等价,但约定俗成把关键字大写、标识符小写,可读性差别很大。注释用--开头,注释内容不会被执行,适合给复杂条件留说明。
-- 这条注释解释下面查询的用途:统计加州客户 SELECT * FROM customers WHERE state = 'CA' ORDER BY first_name LIMIT 3;这段示例把前面几块拼在了一起:选表、过滤、排序、截取,一条语句走完单表查询全流程,适合当作复习时的默写模板。
5. 易错点清单:五个不报错却让结果悄悄错掉的坑
梳理下来会发现,SQL 入门阶段的错误分两类:一类会报错,好查;另一类语法完全合法、结果却是错的,这类才是复习的真正重点。下面五条按「易漏点 → 为什么漏 → 怎么补」展开。
易漏点一:用= NULL判断空值。为什么漏:直觉上「等于空」说得通,语法也不报错。怎么补:空值判断一律用IS NULL/IS NOT NULL,写完条件后扫一眼有没有= NULL这种写法。
易漏点二:AND与OR混用不加括号。为什么漏:AND优先级高于OR,语句照常执行。怎么补:只要一条 WHERE 里同时出现AND和OR,就给每个逻辑分组加括号,宁可多写不省略。
易漏点三:内连接与外连接选错。为什么漏:两种写法都合法,区别只在结果行数。怎么补:写 JOIN 前先问「没匹配的主体要不要保留」,要就LEFT JOIN,并用「左表行数 = 结果行数」做一次自检。
易漏点四:BETWEEN边界理解成开区间。为什么漏:其他语言里区间常是半开的,习惯迁移过来就错。怎么补:记住BETWEEN a AND b两端都含,涉及边界值断言时手动验证 a 和 b 本身是否被选中。
易漏点五:DISTINCT以为只作用于第一列。为什么漏:单列去重时表现正常,多列时才暴露。怎么补:DISTINCT作用于整行组合,多列去重前先想清楚「我要的唯一性到底是哪几列的组合」。
提示:这五条的共同点是「不报错」。复习时不要只跑通示例,要故意构造边界数据去验证,比如插一条
phone为空的记录再跑IS NULL查询。
6. 复习落地:一份可以照着走的自查流程
知识地图讲完,最后落到怎么用。复习 SQL 最忌讳「看一遍觉得都会,一写就卡」。我的做法是把这份笔记当检查表,按下面的顺序过一遍,每步都要求自己不看笔记手写出来,写不出就标记回炉。
| 复习步骤 | 自查动作 | 通过标准 |
|---|---|---|
| 单表查询 | 手写一条含表达式、别名、去重的 SELECT | 能说清执行顺序 |
| 条件过滤 | 写一条同时含 AND、OR、NOT 的 WHERE | 括号位置正确 |
| 模式匹配 | 用 LIKE 和 REGEXP 各写一个前缀匹配 | 能说出两者差异 |
| 空值处理 | 写 IS NULL 与 IS NOT NULL 各一条 | 不出现= NULL |
| 多表连接 | 同一需求分别用 JOIN 和 LEFT JOIN 写 | 能解释行数差异 |
| 结果拼接 | 用 UNION 合并两个结果集 | 知道 UNION ALL 的区别 |
| 数据写入 | 写单行和多行 INSERT | 显式列出列名 |
具体操作上,建议准备一张小表(比如客户表加订单表),把上面每一步的语句真实跑一遍,然后故意改坏一个条件,观察结果怎么变。比如把LEFT JOIN改成JOIN,看少了哪些行;把IS NULL改成= NULL,看结果是不是空了。这种「破坏性验证」比正向跑通更能暴露理解漏洞。
还有一个习惯值得养成:每写完一条多条件查询,先单独跑 WHERE 部分看筛出多少行,再套上 JOIN 和 ORDER BY,逐层确认行数变化符合预期。行数是最诚实的黑匣子,多出来的行往往就是漏写的连接条件或写错的逻辑分组。
从那以后我每次复习 SQL 都强制走一遍「手写 → 跑通 → 故意改坏 → 解释差异」这个循环,比反复看笔记有效得多。这份三小时课程的笔记正好可以当这个循环的底稿,把上面几章的语句当模板,缺哪块补哪块。希望帮到你。
本文还有配套的精品资源,点击获取