首页 / 资讯中心 / 文章详情

SQL三小时笔记:从SELECT到多表JOIN的完整知识骨架

SQL三小时笔记:从SELECT到多表JOIN的完整知识骨架 ★ FEATURED ARTICLE
简介这份资源是B站Mosh老师SQL三小时入门课程的配套笔记以PDF形式整理面向零基础或希望系统梳理SQL核心语法的开发者与数据分析初学者。内容覆盖SQL基础知识、SELECT语句、WHERE子句以及逻辑操作符、IN、BETWEEN、LIKE、REGEXP等常用操作符并延伸至IS NULL、ORDER BY、LIMIT、各类JOIN与UNION等查询要点帮助读者快速建立完整的SQL知识框架。资源包内共1个PDF文件大小约2.43MB轻量便携适合随时查阅与复习。目前已有976人学习下载说明其在入门学习者中具有一定认可度。笔记以速查表形式组织条理清晰便于对照语法示例理解条件筛选、模式匹配与多表连接等实际用法适合作为课程学习后的巩固材料或日常开发中的快速参考手册。1. SQL 三小时笔记的知识地图从一条 SELECT 到多表 JOIN 的完整骨架很多人学 SQL 的路径是反的先背JOIN的四种类型再回头补WHERE和ORDER BY结果写查询时脑子里是一堆碎片。这份笔记的价值在于它给了一条清晰的骨架——从单表查询到多表关联每一步只增加一个概念。整张地图大致分四层第一层是基础语法注释、分号、大小写第二层是单表查询SELECT、WHERE、逻辑运算符、IN、BETWEEN、LIKE、REGEXP、IS NULL第三层是结果集加工ORDER BY、LIMIT第四层是多表操作INNER JOIN、OUTER JOIN、USING、CROSS JOIN、UNION和数据写入INSERT。适合已经能写简单查询、但知识点散落一地的人拿来重新串一遍。下面按这条骨架逐层拆开把每个子句的语法、参数含义和容易翻车的地方都过一遍。2. 单表查询的六个过滤工具WHERE、逻辑运算符与模式匹配2.1 WHERE 子句与比较运算符过滤的起点WHERE是所有过滤逻辑的入口它跟在FROM后面对每一行做条件判断只保留条件为真的行。比较运算符一共六个、、、、、或!。这里最容易忽略的是和!在 MySQL 里完全等价但有些数据库只认其中一种写笔记时最好两个都记上。-- 筛选积分大于 1000 的客户 SELECT * FROM customers WHERE points 1000;参数说明points是列名1000是阈值表示严格大于。如果要包含等于必须写成这是最常见的边界错误——很多人写BETWEEN 100 AND 200时以为不包含端点实际上 MySQL 的BETWEEN是闭区间两端都包含。2.2 逻辑运算符 AND、OR、NOT组合条件的优先级陷阱AND要求两边都为真OR只要一边为真NOT对条件取反。单独用都不难难的是混用时的优先级AND的优先级高于OR所以A OR B AND C会被解释成A OR (B AND C)而不是(A OR B) AND C。血泪经验是只要同时出现AND和OR一律加括号别赌自己的记忆。-- 出生日期在 1990 年之后或者积分大于 1000 SELECT * FROM customers WHERE birthdate 1990-01-01 OR points 1000; -- 用 NOT 取反出生日期不在 1990 年之后 SELECT * FROM customers WHERE NOT (birthdate 1990-01-01);NOT后面跟括号是安全写法如果写成NOT birthdate 1990-01-01虽然也能跑但可读性差复习时容易看错逻辑。2.3 IN 与 BETWEEN列表匹配和区间匹配IN用来判断某个值是否在一个离散列表里BETWEEN判断是否在连续区间内。两者都能用OR改写但IN和BETWEEN更短、更不容易写错。-- 客户来自 VA、NY、CA 三个州 SELECT * FROM customers WHERE state IN (VA, NY, CA); -- 积分在 100 到 200 之间包含两端 SELECT * FROM customers WHERE points BETWEEN 100 AND 200;重点IN的列表里可以放数字、字符串、日期但类型要一致BETWEEN对小值在前、大值在后有要求写反了会返回空结果而且不报错——这是最隐蔽的翻车点之一。2.4 LIKE 与 REGEXP两种模式匹配的分工LIKE只支持两个通配符%匹配任意数量字符_匹配恰好一个字符。REGEXP支持正则表达式能力更强但写法也更复杂。-- 名字以 b 开头 SELECT * FROM customers WHERE first_name LIKE b%; -- 名字以 a 开头正则写法 SELECT * FROM customers WHERE first_name REGEXP ^a; -- 名字以 ey 或 on 结尾 SELECT * FROM customers WHERE first_name REGEXP ey$|on$; -- 名字包含 b 后面跟着 r 或 u SELECT * FROM customers WHERE first_name REGEXP b[ru];正则元字符速查^表示字符串开头$表示结尾|表示或[abc]匹配其中任意一个字符[a-d]匹配 a 到 d 范围内的任意字符。梳理下来会发现LIKE能做的事REGEXP都能做但LIKE在简单前缀匹配时性能更好日常查询优先用LIKE复杂模式再上REGEXP。2.5 IS NULL空值的专用判断NULL在 SQL 里不是 0也不是空字符串它代表“未知”。任何值与NULL做比较运算包括 NULL结果都不是真所以必须用IS NULL或IS NOT NULL。-- 找出没有电话号码的客户 SELECT * FROM customers WHERE phone IS NULL;易错点WHERE phone NULL不会报错但永远返回空结果。这个坑几乎每个人都会踩一次记住“空值只能用 IS 判断”就能避开。3. 结果集加工与多表关联ORDER BY、LIMIT 和四种 JOIN3.1 ORDER BY 与 LIMIT排序和截断的执行顺序ORDER BY按指定列排序默认升序ASC可以显式写DESC降序。多列排序时先按第一列排第一列相同的再按第二列排。LIMIT用来限制返回行数LIMIT 6, 3表示跳过前 6 行返回接下来的 3 行——注意第一个数字是偏移量不是起始行号。-- 先按州升序再按名字降序 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在WHERE之后执行LIMIT在ORDER BY之后执行。如果先LIMIT再排序结果就是错的。另外LIMIT的偏移量写法在数据量大时性能会下降复习时知道这个背景即可。3.2 INNER JOIN 与 OUTER JOIN匹配与不匹配的分界INNER JOIN只返回两张表中匹配的行LEFT JOIN返回左表全部行右表没有匹配的用NULL填充。RIGHT JOIN反过来但实际写查询时几乎都用LEFT JOIN因为可以调整表顺序达到同样效果。-- 内连接只返回有订单的客户 SELECT * FROM customers c JOIN orders o ON c.customer_id o.customer_id; -- 左连接返回所有客户包括没有订单的 SELECT * FROM customers c LEFT JOIN orders o ON c.customer_id o.customer_id;参数说明c和o是表别名ON后面是连接条件。梳理下来会发现JOIN默认就是INNER JOIN写不写INNER都一样。LEFT JOIN的结果里右表列出现NULL就说明该行在右表没有匹配——这是排查“哪些客户没下过单”的标准手法。3.3 USING、CROSS JOIN 与 UNION简化写法和集合合并当两张表的连接列名完全相同时可以用USING替代ON写法更短。CROSS JOIN返回笛卡尔积把左表每一行和右表每一行组合实际业务里用得少但理解它有助于明白JOIN的本质。UNION把两个查询结果上下拼在一起要求列数和类型一致。-- USING 简化连接 SELECT * FROM customers c JOIN orders o USING (customer_id); -- 交叉连接每种颜色配每种尺寸 SELECT * FROM colors CROSS JOIN sizes; -- 合并客户和潜在客户的名字与地址 SELECT name, address FROM customers UNION SELECT name, address FROM clients;注意UNION会自动去重如果不想去重就用UNION ALL。CROSS JOIN的结果行数是两张表行数的乘积小表测试时没问题大表上跑就是灾难复习时记住这个数量级关系。3.4 INSERT INTO写入数据的两种形式INSERT INTO用来向表中添加行可以一次插一条也可以一次插多条。列名列表和值列表要一一对应不想赋值的列可以用DEFAULT让数据库填默认值。-- 插入单条记录 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);重点NULL是显式写入空值DEFAULT是让数据库用该列的默认值两者含义不同。如果列有NOT NULL约束且没有默认值插入时省略该列会报错。4. 易漏点与易错点五个复习时最容易翻车的地方4.1 易漏点一BETWEEN 的边界包含关系为什么漏很多教程只说“在什么范围内”不强调是否包含端点导致写查询时凭感觉。怎么补记住 MySQL 的BETWEEN是闭区间BETWEEN 100 AND 200包含 100 和 200。如果要不包含端点必须用 100 AND 200。4.2 易漏点二NULL 的比较运算永远不为真为什么漏NULL在直觉上像“空”容易当成一个普通值去比较。怎么补所有涉及NULL的判断一律用IS NULL或IS NOT NULL写完查询后专门检查一遍有没有 NULL的写法。4.3 易漏点三AND 和 OR 混用时的优先级为什么漏AND优先级高于OR这件事在简单例子里看不出来一旦条件变多就出错。怎么补只要同时出现AND和OR无条件加括号把逻辑分组写清楚别依赖默认优先级。4.4 易漏点四LEFT JOIN 后 WHERE 过滤右表列会退化成 INNER JOIN为什么漏LEFT JOIN的本意是保留左表全部行但如果在WHERE里对右表列加条件比如WHERE o.status shipped右表为NULL的行会被过滤掉结果和内连接一样。怎么补如果确实要保留左表全部行右表的过滤条件应该写在ON后面而不是WHERE里。4.5 易漏点五LIMIT 偏移量的含义为什么漏LIMIT 6, 3看起来像“从第 6 行开始取 3 行”实际是“跳过 6 行取 3 行”起始行是第 7 行。怎么补把LIMIT offset, count读成“跳过 offset 条返回 count 条”写分页查询时用(页码 - 1) * 每页条数算偏移量。5. 复习清单三小时笔记的查漏补缺路线复习这份笔记最有效的方式不是从头再读一遍而是按“写查询的顺序”反向检查。下面这张清单按实际写 SQL 时的决策顺序排列每一条都对应一个可以立刻验证的动作。检查项验证方式对应知识点表名和列名是否写对先SELECT *跑一次FROM / SELECT过滤条件是否覆盖边界手动代入端点值测试WHERE / BETWEEN空值判断是否用 IS搜索查询里有没有 NULLIS NULLAND/OR 是否加括号把条件单独跑一遍对比结果逻辑运算符模式匹配是否用对通配符%和_分别测试LIKE / REGEXP排序和截断顺序是否正确先去掉 LIMIT 看全量排序ORDER BY / LIMITJOIN 类型是否匹配需求左表行数是否全部保留INNER / LEFT JOIN右表过滤是否写在 ON 里检查 WHERE 里有没有右表列LEFT JOIN 退化UNION 是否需要去重对比 UNION 和 UNION ALL 行数UNIONINSERT 列和值是否一一对应数一遍列名和值的个数INSERT INTO这份清单可以打印出来贴在显示器旁边每次写完查询逐条过一遍。我自己的习惯是只要查询里同时出现JOIN和WHERE就强制走一遍第 7 和第 8 项因为这两个地方翻车最多而且不报错只是结果悄悄变少。从那以后我每次写多表查询都先把LEFT JOIN的左表行数单独查一遍再对比最终结果行数不一致就回头查WHERE条件。希望这份梳理帮到你。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?
咨询建站