ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

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 的路径是反的:先背语法,再刷题,最后才发现自己连「一条查询语句在数据库里按什么顺序执行」都说不清。这份三小时课程配套的速查表,价值不在于它列了多少关键字,而在于它把入门阶段真正高频的东西压缩成了一条主线:选表 → 过滤 → 排序 → 限量 → 连接 → 合并 → 写入。你把这七个动作串起来,SQL 的骨架就立住了。

它适合两类人:一类是刚接触关系型数据库、需要一张能贴在显示器边上的地图的人;另一类是学过一阵子、写查询全靠试、想回头把基础重新捋顺的人。速查表本身不是教程,它更像索引——每个语法点后面都对应着一段可以立刻验证的查询。下面按模块拆开,把「是什么」和「重点在哪」一起讲清楚,最后落到一份能自查的复习清单上。

2. 查询骨架:SELECT、WHERE 与表达式求值的复习重点

2.1 SELECT 不只是选列,表达式和别名才是重点

入门时最容易把 SELECT 理解成「挑几列出来」,但速查表里第一个例子就是表达式:SELECT (points * 10 + 20) AS discount_factor FROM customers。这里有两个必须记住的点。第一,SELECT 后面可以跟任意表达式,不只是列名,算术、函数、常量都能放。第二,AS起别名不是可有可无的装饰,它决定了结果集里这一列的列名,后续如果这层查询被当成子查询或视图,别名就是唯一能引用它的名字。

运算优先级也在这条例子里:括号 → 乘除 → 加减。看起来是小学数学,但实际写业务查询时,points * 10 + 20和points * (10 + 20)差一个数量级,翻车往往就翻在这。另一个高频点是DISTINCT:SELECT DISTINCT state FROM customers去重作用于整行结果,不是某一列。选了多列再 DISTINCT,只有所有列的组合完全一致才会被合并,这一点很多人第一次用都会误解。

-- 表达式 + 别名:结果列名由 AS 决定 SELECT (points * 10 + 20) AS discount_factor FROM customers; -- DISTINCT 作用于整行组合,不是单列 SELECT DISTINCT state FROM customers;

参数说明:points是数值列,参与算术时按行计算;AS discount_factor是列别名,别名里不要用空格和特殊字符,需要时用反引号包起来。写表达式时养成先加括号的习惯,比事后排查优先级便宜得多。

2.2 WHERE 的比较运算符与逻辑组合

WHERE 的作用是逐行判断,只留下条件为真的行。速查表列了六个比较运算符:>、>=、<、<=、=、<>(等价于!=)。这里有个新手常踩的坑:SQL 里判断相等是单个=,不是==;不等有两种写法,<>是标准写法,!=在 MySQL 里也能用,但跨数据库移植时优先用<>。

逻辑运算符 AND、OR、NOT 的组合才是 WHERE 的真正难点。AND 要求两边都为真,OR 只要一边为真,NOT 取反。重点在于优先级:AND 的优先级高于 OR,所以A OR B AND C实际等价于A OR (B AND C)。如果你想要的是「(A 或 B) 且 C」,必须显式加括号。速查表里WHERE NOT (birthdate > '1990-01-01')这个写法就是在提醒你,NOT 后面跟复合条件时括号不能省。

-- AND:两个条件同时满足 SELECT * FROM customers WHERE birthdate > '1990-01-01' AND points > 1000; -- OR:满足其一即可 SELECT * FROM customers WHERE birthdate > '1990-01-01' OR points > 1000; -- NOT 取反,复合条件必须加括号 SELECT * FROM customers WHERE NOT (birthdate > '1990-01-01');

日期写成字符串'1990-01-01'是 MySQL 的隐式转换,标准写法是DATE '1990-01-01',入门阶段用字符串没问题,但要知道这是数据库在帮你兜底,不是语法本身宽松。

2.3 范围、集合与空值:IN、BETWEEN、IS NULL 的边界

IN用来判断某列的值是否落在一个列表里,WHERE state IN ('VA', 'NY', 'CA')比写三个 OR 干净得多,而且列表可以来自子查询。BETWEEN判断闭区间,WHERE points BETWEEN 100 AND 200包含 100 和 200 两个端点,这一点和某些语言里左闭右开区间不同,考试和面试都爱在这里设陷阱。

IS NULL是另一个高频易错点。NULL 表示「未知」,它不等于任何值,也不等于另一个 NULL。所以WHERE phone = NULL永远返回空结果,必须写WHERE phone IS NULL。同理,判断非空用IS NOT NULL。速查表专门把这条单列出来,就是因为它是入门阶段最典型的「语法没错但结果不对」。

-- IN:集合匹配,列表可长可短 SELECT * FROM customers WHERE state IN ('VA', 'NY', 'CA'); -- BETWEEN:闭区间,两端都包含 SELECT * FROM customers WHERE points BETWEEN 100 AND 200; -- IS NULL:判断空值,不能用 = NULL SELECT * FROM customers WHERE phone IS NULL;

提示:任何参与比较的列只要可能为 NULL,就要先想清楚「这行该不该出现在结果里」,再决定用 IS NULL、IS NOT NULL 还是加 COALESCE 兜底。

2.4 模式匹配:LIKE 与 REGEXP 的分工

LIKE是通配符匹配,两个符号必须记牢:%代表任意数量字符(包括零个),_代表恰好一个字符。WHERE first_name LIKE 'b%'是以 b 开头,LIKE '%b%'是包含 b,LIKE '_b%'是第二个字符为 b。注意%放在开头会导致索引失效,数据量大时这是性能分水岭。

REGEXP是正则匹配,能力更强。速查表给的锚点和字符类要背下来:^开头、$结尾、|逻辑或、[abc]匹配其中任一单字符、[a-d]匹配区间内任一字符。几个组合例子值得反复看:'ey$|on$'是以 ey 或 on 结尾,'^my|se'是以 my 开头或包含 se,'b[ru]'是 b 后面跟 r 或 u。这里最容易错的是把|的作用范围想当然——它默认作用于整个模式的两侧,需要限定范围时用括号分组。

-- LIKE:% 任意多字符,_ 恰好一个字符 SELECT * FROM customers WHERE first_name LIKE 'b%'; -- REGEXP:锚点与字符类组合 SELECT * FROM customers WHERE first_name REGEXP 'ey$|on$'; -- 以 ey 或 on 结尾 WHERE first_name REGEXP '^my|se'; -- 以 my 开头或包含 se WHERE first_name REGEXP 'b[ru]'; -- b 后跟 r 或 u

2.5 排序与限量:ORDER BY 与 LIMIT 的执行位置

ORDER BY默认升序,多列排序时按书写顺序依次生效:ORDER BY state, first_name DESC表示先按 state 升序,state 相同的再按 first_name 降序。注意DESC只作用于紧挨着它的那一列,不是整条语句。想要两列都降序,得写两次DESC。

LIMIT有两个参数形态:LIMIT 3取前三条,LIMIT 6, 3表示跳过 6 条再取 3 条,等价于LIMIT 3 OFFSET 6。分页场景下这个偏移量写法很常用,但偏移越大越慢,因为数据库仍要扫过前面那些行。排序和限量通常一起出现,逻辑顺序是「先过滤、再排序、最后截断」,写查询时按这个顺序想,就不会把 LIMIT 放到 WHERE 前面去。

3. 多表与写入:连接、合并、插入的易错点集中区

3.1 内连接与外连接:结果集差异才是考点

JOIN默认就是内连接,只保留两张表都能匹配上的行。速查表里的写法是FROM customers c JOIN orders o ON c.customer_id = o.customer_id,c和o是表别名,ON后面写连接条件。内连接的重点不是语法,而是「匹配不上就丢」这个语义——如果某个客户没有任何订单,他在结果里直接消失。

外连接分左右:LEFT JOIN保留左表全部行,右表匹配不上就补 NULL;RIGHT JOIN反过来。速查表用LEFT JOIN演示「返回所有客户,无论有没有订单」,这正是外连接存在的意义。判断该用哪种连接,问自己一句:哪张表的行一行都不能少?那张表放左边用 LEFT JOIN,放右边用 RIGHT JOIN。很多人写外连接后又在 WHERE 里对右表列加= 某值的条件,结果把 NULL 行全过滤掉了,外连接退化成内连接,这是最隐蔽的翻车点之一。

-- 内连接:只保留两表都匹配的行 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;

3.2 USING、CROSS JOIN 与 UNION 的适用边界

当两张表的连接列名完全相同时,可以用USING (customer_id)替代ON c.customer_id = o.customer_id,写法更短,结果集里该列也只出现一次。但要注意 USING 要求列名严格一致,列名不同就只能老老实实写 ON。

CROSS JOIN是笛卡尔积,左表每一行和右表每一行两两组合。速查表用「每种颜色配每种尺寸」举例,很直观。它的结果行数是两表行数之积,误用会瞬间炸出巨量数据,所以只在确实需要全组合时用。

UNION把多个结果集纵向拼起来,要求列数和对应列的数据类型兼容。默认会去重,想保留重复用UNION ALL。速查表里SELECT name, address FROM customers UNION SELECT name, address FROM clients就是典型用法。重点在于:UNION 是按列的位置对齐的,不是按列名,所以两个 SELECT 的列顺序必须一致,否则拼出来的数据会错位,而且不会报错。

-- USING:连接列同名时的简写 SELECT * FROM customers c JOIN orders o USING (customer_id); -- CROSS JOIN:两两组合,行数为两表行数之积 SELECT * FROM colors CROSS JOIN sizes; -- UNION:纵向合并,按列位置对齐,默认去重 SELECT name, address FROM customers UNION SELECT name, address FROM clients;

3.3 插入数据:单行、多行与 DEFAULT 的写法

INSERT INTO的完整形态是「表名 + 列清单 + VALUES + 值清单」。列清单建议永远写全,不写的话值必须按表定义顺序一一对应,表结构一改就出问题。速查表给了单行和多行两种写法,多行插入用逗号分隔每组值,比循环执行多条 INSERT 快得多。

DEFAULT关键字表示「这一列用表定义的默认值」,配合可空列写NULL也很常见。注意列清单里没出现的列,如果有默认值会自动填默认值,没有默认值且不允许 NULL 就会报错。这是插入语句最常见的失败原因,排查时先看表结构里哪些列是 NOT NULL 且无默认值。

-- 单行插入,列清单写全 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);

4. 易错点清单:这五处最容易在复习时被跳过

易错点一:把= NULL当成判空。为什么漏:直觉上「等于空」很自然,语法也不报错。怎么补:记住 NULL 参与的任何比较结果都是未知,判空只用IS NULL/IS NOT NULL,写完查询先扫一遍有没有= NULL。

易错点二:AND 与 OR 混用不加括号。为什么漏:AND 优先级高这条规则藏在细节里,单看语句读不出歧义。怎么补:只要 WHERE 里同时出现 AND 和 OR,一律给每个逻辑分组加括号,宁可多写也不靠优先级。

易错点三:外连接后在 WHERE 里过滤右表列。为什么漏:语句能跑通,结果也「看起来对」,只是悄悄少了行。怎么补:外连接后对右表的过滤条件优先写进 ON 子句,写进 WHERE 就要意识到自己在丢弃 NULL 行。

易错点四:UNION 两边列顺序不一致。为什么漏:不报错,数据错位后很难第一时间发现。怎么补:合并前把两个 SELECT 的列清单并排写出来核对位置,列名不同没关系,位置和类型必须对齐。

易错点五:LIKE 以%开头还指望走索引。为什么漏:小数据量下完全无感,数据涨上来才暴露。怎么补:前缀模糊匹配尽量改成后缀或精确匹配,必须前缀模糊时考虑全文检索方案,别在复习阶段只记语法不记代价。

5. 复习落地:一份能自查的 SQL 基础清单

把上面几章压成一张自查表,复习时逐行过,能立刻说出写法和易错点的打勾,卡住的回去看对应小节。这张表也是我后来每次带新人时固定走一遍的流程,比从头翻教程快得多。

模块必须能默写自查问题
SELECT表达式 + AS 别名、DISTINCTDISTINCT 作用于单列还是整行?
WHERE六个比较运算符、AND/OR/NOTAND 和 OR 混用时括号加了吗?
集合与范围IN、BETWEEN、IS NULLBETWEEN 两端包不包含?判空能用 = 吗?
模式匹配LIKE 的 % 和 _、REGEXP 锚点%开头对索引有什么影响?
排序限量ORDER BY 多列、LIMIT 两种形态DESC 作用于哪一列?LIMIT 6,3 跳过几条?
连接INNER / LEFT / RIGHT、USING哪张表的行不能少?过滤条件写 ON 还是 WHERE?
合并UNION 与 UNION ALL两边列顺序对齐了吗?
写入单行/多行 INSERT、DEFAULT列清单写全了吗?NOT NULL 列有默认值吗?

具体怎么用这张表:第一遍不看答案,凭记忆把「必须能默写」那列在纸上写出来;第二遍对照速查表原文改错,错的地方标红;第三遍只过标红项,直到能连续两遍全对。整个过程控制在四十分钟以内,比重看三小时视频效率高得多。

还有一个习惯值得养成:每写一条查询,先在脑子里过一遍执行顺序——FROM 找表、WHERE 过滤、SELECT 取列算表达式、ORDER BY 排序、LIMIT 截断。顺序想对了,语法错误和逻辑错误会同时少一大半。我早期写多表查询时总在 ON 和 WHERE 之间来回改,后来强制自己先画两张表的行集合再动键盘,翻车的次数明显降下来。希望这份梳理帮到你,复习时少走几段弯路。

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

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进