ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

三小时SQL速通地图:单表查询、多表连接与易错点全解析

三小时SQL速通地图:单表查询、多表连接与易错点全解析

简介:这份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 都强制走一遍「手写 → 跑通 → 故意改坏 → 解释差异」这个循环,比反复看笔记有效得多。这份三小时课程的笔记正好可以当这个循环的底稿,把上面几章的语句当模板,缺哪块补哪块。希望帮到你。

本文还有配套的精品资源,点击获取

返回列表