SQL笔记
学习SQL写法 && 数据库一些用法 的笔记
JOIN
- 数据分散到多个表时,需要用表连接来关联数据
- 每个join操作都会生成一个中间表,根据需要去进一步操作
结构
1 | SELECT 表1.字段, 表2.字段 |
内连接
只返回两表之中满足条件的记录(交集)
1 | SELECT * |
左连接
返回左表(表 A)的 所有记录,右表(表 B)中匹配的记录,若右表无匹配则用 NULL 填充
1 | SELECT * |
右链接
返回右表(表 B)的 所有记录,左表(表 A)中匹配的记录,若左表无匹配则用 NULL 填充
1 | SELECT * |
全外链接
返回两表的 所有记录,匹配的记录合并,不匹配的字段用 NULL 填充(并集)
1 | SELECT * |
MySQl不支持上面的写法,下面是替代方案
1 | SELECT * |
多表联查
1 | SELECT * |
笛卡尔积
CROSS JOIN
是一种用于组合两个表中所有可能的行组合的链接方式
- 生成全部组合:如果表 A 有 m 行,表 B 有 n 行,A CROSS JOIN B 会生成 m×n 行的结果集
- 无关联条件:不同于 INNER JOIN 或 LEFT JOIN,CROSS JOIN 不使用 ON 子句指定连接条件
- 应用场景:通常用于生成所有可能的组合,如学生与科目的全排列、日期与产品的组合等
示例
1 | -- 学生表 Students |
结果
1 | +------------+--------------+--------------+ |
例题:学生们参加各科考试的次数
聚合函数
- 对一组数据进行计算返回单一结果值,只能在SELECT和HAVING中使用
- 除了COUNT(*),自动忽略NULL值
COUNT()
- COUNT(*):统计所有行(包括含 NULL 的行)
- COUNT(列名):统计该列中非 NULL 值的数量
- COUNT(DISTINCT 列名):统计该列中不同值的非 NULL 数量
SUM()
- 获取数值列的总和,忽略NULL
AVG()
- 数值列的平均值,忽略NULL
MAX()/MIN()
- 数值列最大最小值,忽略NULL
分组
- GROUP BY 子句用于将数据按一个或多个列分成不同的组,以便对每个组分别应用聚合函数,得到每组的汇总结果
1 | SELECT 分组列, 聚合函数(其他列) |
日期函数
日期计算函数
- DATE_ADD(date, INTERVAL value unit):日期加法
- DATE_SUB(date, INTERVAL value unit):日期减法
- DATEDIFF(end_date, start_date):返回两个日期之间的天数差(end_date - start_date)
筛选数据的子句
子句 | 执行时机 | 作用对象 | 是否支持聚合函数 | 典型用法 | 示例 |
---|---|---|---|---|---|
WHERE | 在 FROM 之后、GROUP BY 之前 | 原始表中的行 | ❌ 不支持 | 过滤原始数据中的行 | SELECT * FROM Employees WHERE salary > 50000; |
ON | 在表连接(JOIN )时执行 | 表连接的匹配条件 | ❌ 不支持 | 定义表之间的关联规则 | LEFT JOIN Managers ON Employees.managerId = Managers.id; |
HAVING | 在 GROUP BY 之后、SELECT 之前 | 分组后的聚合结果 | ✅ 支持 | 筛选分组后的统计结果 | SELECT dept_id, COUNT(*) AS cnt FROM Employees GROUP BY dept_id HAVING cnt > 5; |
关键差异总结:
执行顺序:
FROM
→ON
(连接时)→WHERE
→GROUP BY
→HAVING
→SELECT
→ORDER BY
核心区别:
WHERE
:先过滤再处理,用于原始数据的行级筛ON
:边连接边过滤,用于控制表连接的匹配规则(尤其在LEFT JOIN
中保留主表行)HAVING
:先分组聚合再过滤,必须与GROUP BY
配合使用,用于筛选聚合后的结果(如COUNT
、SUM
等)
特殊场景:
- 在
LEFT JOIN
中,ON
条件不满足时会保留主表行(对应字段为NULL
),而WHERE
会直接排除这些行 HAVING
可以引用SELECT
中的别名(需注意数据库兼容性),而WHERE
不行
- 在
数据库知识补遗
外键
- 强制数据完整性,简化挂你先维护
学生表(Students):student_id(主键), name, class_id
班级表(Classes):class_id(主键), class_name
这里,Students.class_id 就是外键,它引用了 Classes.class_id,确保学生所属的班级必须存在于 Classes 表中
- 不能引用不存在的数据:例如,添加一个学生时,如果指定的 class_id 在 Classes 表中不存在,数据库会拒绝这个操作
- 不能随意删除关联数据:如果 Classes 表中的某个班级被学生引用,直接删除该班级会导致引用无效,数据库通常会阻止这种删除(或级联删除关联数据)
- 当更新 Classes.class_id 时,外键可以自动级联更新 Students.class_id(如果配置了级联更新)
- 当删除 Classes 中的班级时,外键可以级联删除所有关联的学生(如果配置了级联删除)
All articles on this blog are licensed under CC BY-NC-SA 4.0 unless otherwise stated.