简介:这份资源是B站Mosh老师SQL三小时入门课程的配套笔记,面向零基础或希望系统梳理SQL核心语法的开发者与数据分析初学者,帮助读者在短时间内建立对关系型数据库查询语言的完整认知。资源包为单个PDF文件,大小约2.43MB,内容以速查表形式组织,涵盖SQL基础知识、SELECT子句、WHERE子句、逻辑操作符、IN、BETWEEN、LIKE、REGEXP、IS NULL、ORDER BY、LIMIT以及内连接、外连接、USING、交叉连接、UNION、数据插入等核心语法模块,并配有简洁的代码示例与语法结构说明。目前已有976人学习下载,适合作为日常查阅手册或配合视频课程同步练习。读者可借助这份笔记快速掌握条件筛选、模式匹配、结果排序与多表关联等常用操作,形成可随时翻阅的SQL知识索引,提升查询编写与调试效率。
1. 到底什么是 SQL:从一张“点菜清单”说起
如果你完全没接触过数据库,听到 SQL 这个词可能会觉得它离自己很远。其实它就像你去餐厅点菜时写的那张单子——你不需要知道后厨怎么切菜、怎么开火,只需要用一套双方都认得的写法,告诉服务员“我要什么、不要什么、按什么顺序上”。SQL 就是人和数据库之间那套约定好的“点菜语言”,全称叫结构化查询语言,专门用来跟关系型数据库打交道。
它值得搞懂的原因很直接:今天几乎所有需要存数据的地方——手机里的通讯录、购物网站的订单、公司后台的客户名单——背后都站着一个数据库,而 SQL 就是打开这些数据的钥匙。不管底层用的是 MySQL、PostgreSQL 还是 SQL Server,核心的查询思路是相通的。这份课程笔记把 SQL 最常用的那部分语法浓缩成了一份速查表,从 SELECT 到 JOIN 再到插入数据,覆盖了日常写查询时八成以上的场景。搞懂它,你就有了跟数据对话的基本能力。
2. 为什么 SQL 长这样:从一句查询拆开看
2.1 一条语句的骨架:SELECT 和 FROM 到底在干什么
很多人第一次看到 SQL 语句会觉得它像英语句子,但又不太确定每个词的作用。拿最基础的一条来看:
SELECT * FROM customers WHERE state = 'CA' ORDER BY first_name LIMIT 3;这条语句的意思是:从 customers 这张表里,找出 state 等于 CA 的记录,按 first_name 排序,只返回前 3 条。SELECT 后面跟的是“你要哪些列”,星号代表全部列;FROM 后面跟的是“从哪张表拿”;WHERE 是筛选条件;ORDER BY 决定排序方式;LIMIT 控制返回条数。这五个部分基本构成了一条查询的完整骨架。
SQL 本身不区分大小写,SELECT 和 select 效果一样,但习惯上关键字用大写、表名和列名用小写,读起来更清楚。另外在 MySQL 里每条语句末尾必须加分号,这是告诉数据库“这句话说完了”。注释用两个短横线开头,写给自己或同事看的说明,数据库执行时会自动跳过。
2.2 筛选的层次:WHERE、逻辑操作符和那几个专用操作符
WHERE 是 SQL 里最常用的筛选工具,它支持一套比较操作符:大于、大于等于、小于、小于等于、等于、不等于。不等于有两种写法,<>和!=,效果一样。这些操作符可以单独用,也可以用逻辑操作符组合起来。
AND 要求两边条件同时成立,OR 只要一边成立就行,NOT 则是把条件反过来。比如你想找生日在 1990 年之后且积分超过 1000 的客户,就用 AND 把两个条件连起来;如果改成 OR,就变成“只要满足其中一个就算”。NOT 用得少一些,但在排除某些记录时很方便。
除了比较操作符,SQL 还提供了几个专用操作符来应对特定场景。IN 用来判断某个值是否在一组候选值里,比如state IN ('VA', 'NY', 'CA')就比写三个 OR 简洁得多。BETWEEN 用来判断一个值是否落在某个区间内,包含两端,比如points BETWEEN 100 AND 200。LIKE 专门做字符串的模式匹配,百分号代表任意多个字符,下划线代表恰好一个字符,所以first_name LIKE 'b%'就是找所有以 b 开头的名字。
REGEXP 比 LIKE 更强大,它支持正则表达式。^表示字符串开头,$表示结尾,竖线表示“或”,方括号表示字符集合。比如first_name REGEXP '^a'找以 a 开头的名字,REGEXP 'ey$|on$'找以 ey 或 on 结尾的名字,REGEXP 'b[ru]'找包含 b 后面跟着 r 或 u 的名字。这些操作符各有各的适用场景,LIKE 适合简单通配,REGEXP 适合复杂模式。
还有一个容易忽略但很重要的操作符是 IS NULL。数据库里的 NULL 表示“没有值”,它不等于空字符串,也不等于零。判断一个字段是不是 NULL 不能用等号,必须用IS NULL,比如WHERE phone IS NULL就是找没有填电话号码的客户。
2.3 排序、截断和去重:让结果按你要的样子出现
查出来的数据默认顺序是不确定的,如果你想让结果按某个规则排列,就得用 ORDER BY。它可以指定一列或多列,每列可以单独指定升序或降序。比如ORDER BY state, first_name DESC就是先按 state 升序排,state 相同的再按 first_name 降序排。升序是默认行为,可以省略 ASC 不写。
LIMIT 用来限制返回的条数。LIMIT 3就是只要前 3 条。它还有一种两个参数的写法,LIMIT 6, 3表示跳过前 6 条,然后取 3 条。这个在分页场景里很常见——比如每页显示 10 条,第二页就从第 11 条开始取。
DISTINCT 是 SELECT 子句里的一个修饰词,用来去掉重复值。比如SELECT DISTINCT state FROM customers返回的是 customers 表里出现过的所有不重复的 state 值。注意 DISTINCT 作用于整行,如果 SELECT 后面跟了多列,它会去掉多列组合完全相同的重复行。
SELECT 后面还可以跟表达式,不只是列名。比如SELECT points * 10 + 20 AS discount_factor就是把 points 列的值做算术运算后返回,AS 给这个计算结果起了个别名。运算顺序和普通数学一样:先算括号,再算乘除,最后算加减。
3. 数据不在一张表里怎么办:JOIN 和 UNION 的用法
3.1 内连接和外连接:到底“保留哪边的全部记录”
真实场景里,数据往往分散在多张表中。客户信息在 customers 表,订单信息在 orders 表,你想同时看到客户和他们的订单,就需要把两张表“接”起来。这个动作叫 JOIN。
最基本的 JOIN 是内连接,写成JOIN或者INNER JOIN都行。它只返回两张表中匹配得上的记录。比如:
SELECT * FROM customers c JOIN orders o ON c.customer_id = o.customer_id这里 c 和 o 是表的别名,用来简化后面列名的书写。ON 后面跟的是连接条件,意思是“customers 表的 customer_id 等于 orders 表的 customer_id”。只有两边都能对上的行才会出现在结果里。如果某个客户没有下过任何订单,他在内连接的结果里就不会出现。
外连接则不同。左外连接写成LEFT JOIN,它会保留左表的所有记录,右表没有匹配的就用 NULL 填充。比如把上面的 JOIN 改成 LEFT JOIN,结果就会包含所有客户,没下过订单的客户在订单相关列上显示 NULL。右外连接RIGHT JOIN反过来,保留右表的全部记录。实际工作中左连接用得最多,因为通常你想保留主表(比如客户表)的全部信息。
3.2 USING 和 CROSS JOIN:两种简化写法和一种特殊组合
如果两张表用来连接的列名完全一样,可以用 USING 来简化 ON 子句。比如JOIN orders o USING (customer_id)和JOIN orders o ON c.customer_id = o.customer_id效果一样,但写起来更短。前提是列名必须一模一样,差一个字母都不行。
CROSS JOIN 是另一种连接方式,它不需要连接条件,直接把左表的每一行和右表的每一行两两组合。比如 colors 表有 3 种颜色,sizes 表有 4 个尺寸,CROSS JOIN 之后就会得到 12 行,每种颜色和每个尺寸的组合都出现一次。这个在生成组合列表时有用,但要注意结果集增长很快,两张各 1000 行的表交叉连接就是一百万行。
3.3 UNION:把两个查询结果上下拼起来
JOIN 是横向扩展列,UNION 是纵向堆叠行。它把两个 SELECT 语句的结果合并成一个结果集。比如你想把 customers 表和 clients 表里的姓名和地址合并成一张列表:
SELECT name, address FROM customers UNION SELECT name, address FROM clientsUNION 要求两个查询返回的列数和对应列的数据类型一致。它默认会去掉完全重复的行,如果不想去重就用 UNION ALL。UNION 和 JOIN 解决的是完全不同的问题:JOIN 是把两张表的列拼在一起,UNION 是把两个结果集的行叠在一起。
4. 几个容易搞混的地方:别在这些概念上翻车
4.1 NULL 和空字符串、零不是一回事
初学者最容易踩的坑就是把 NULL 当成空字符串或者数字零。NULL 在数据库里表示“未知”或“不存在”,它和空字符串''是两个完全不同的东西。空字符串是一个长度为零的字符串,而 NULL 是根本没有值。同样,NULL 也不等于 0。判断一个字段是不是 NULL 必须用IS NULL或IS NOT NULL,不能用= NULL,因为 NULL 和任何值做比较(包括和 NULL 自己比较)结果都不是真。
4.2 WHERE 和 HAVING 不是随便换着用的
WHERE 和 HAVING 都是用来筛选的,但作用时机不同。WHERE 在数据分组之前筛选,HAVING 在分组之后筛选。如果你用了 GROUP BY 做聚合,想对聚合结果加条件,就必须用 HAVING。比如你想找订单总金额超过 1000 的客户,得先按客户分组求和,再用 HAVING 筛选。WHERE 里不能直接用聚合函数,这是硬性规则。
4.3 INNER JOIN 和 LEFT JOIN 的结果差异比想象中大
很多人觉得 JOIN 和 LEFT JOIN 差不多,只是写法不同。实际上当右表没有匹配记录时,INNER JOIN 会直接丢掉左表的这一行,而 LEFT JOIN 会保留它并用 NULL 填充右表的列。这个差异在统计场景里影响很大:如果你用 INNER JOIN 统计每个客户的订单数,没下过单的客户会直接消失;用 LEFT JOIN 才能让那些客户以计数为零的形式出现。
4.4 LIKE 和 REGEXP 的匹配范围不一样
LIKE 只支持两个通配符:百分号匹配任意多个字符,下划线匹配恰好一个字符。REGEXP 支持完整的正则表达式语法,能表达更复杂的模式。但要注意,LIKE 默认不区分大小写(取决于数据库配置),而 REGEXP 在某些数据库里默认区分大小写。另外 LIKE 的百分号是贪婪匹配,会尽可能多地匹配字符,而正则里的量词可以控制贪婪或非贪婪。简单模式用 LIKE 就够了,复杂模式再上 REGEXP。
4.5 LIMIT 6, 3 不是“从第 6 条到第 3 条”
LIMIT 的两个参数写法容易让人误解。LIMIT 6, 3的意思是“跳过前 6 条,然后取 3 条”,不是“取第 6 条到第 3 条”。第一个数字是偏移量,第二个数字是返回条数。偏移量从 0 开始算,所以LIMIT 0, 3和LIMIT 3效果一样,都是取前 3 条。分页的时候,第 n 页(每页 m 条)对应的写法是LIMIT (n-1)*m, m。
5. 什么时候该翻这份速查表:一个真实的使用场景
假设你刚接手一个项目,数据库里有 customers、orders、order_items 三张表。产品经理让你出一份报告:列出每个客户的姓名、订单总数、总消费金额,按消费金额从高到低排,只显示前 10 名。你打开这份速查表,思路会很清晰:先用 LEFT JOIN 把 customers 和 orders 连起来(保证没下过单的客户也在),再用 GROUP BY 按客户分组,用 COUNT 和 SUM 算订单数和总金额,然后用 ORDER BY 按总金额降序,最后 LIMIT 10 取前十。
SELECT c.first_name, COUNT(o.order_id) AS order_count, SUM(o.total) AS total_spent FROM customers c LEFT JOIN orders o ON c.customer_id = o.customer_id GROUP BY c.customer_id, c.first_name ORDER BY total_spent DESC LIMIT 10;这条查询里用到了速查表中的多个知识点:LEFT JOIN 保留所有客户,COUNT 和 SUM 做聚合,GROUP BY 分组,ORDER BY 排序,LIMIT 截断。如果你不知道 LEFT JOIN 和 INNER JOIN 的区别,很可能会用 INNER JOIN 导致没下过单的客户消失;如果你不知道 GROUP BY 之后要用 HAVING 而不是 WHERE,聚合条件就会写错。
但这份速查表也有它的边界。它覆盖的是 SQL 的核心语言构造,不是全部。比如窗口函数、存储过程、事务控制、索引优化这些进阶内容,速查表里没有涉及。如果你要做的是复杂的分析查询或者性能调优,这份笔记只能帮你打好基础,深入的部分还需要专门学习。另外不同数据库的语法有细微差别,比如 MySQL 的 LIMIT 在 SQL Server 里要写成 TOP 或 OFFSET FETCH,日期函数和字符串函数的写法也各不相同。速查表里的示例是基于 MySQL 的,换到别的数据库时需要留意兼容性。
我自己的习惯是:每次写稍微复杂一点的查询之前,先翻一遍这份速查表,确认 JOIN 的类型选对了、WHERE 和 HAVING 没搞混、NULL 处理没漏掉。这个动作花不了两分钟,但能省下大量调试时间。从那以后我每次写多表查询都强制走一遍这个检查流程,翻车次数明显少了。希望帮到你。
本文还有配套的精品资源,点击获取