SQL 语言基础
SQL(Structured Query Language)是关系型数据库的通用语言,按功能可分为四类:
下面以一张订单表为例,贯穿讲解查询的各个构件。
增删改
Warning
UPDATE 与 DELETE 一定要带 WHERE。误操作前可先用 SELECT 验证条件命中行数,并在事务中执行以便回滚。
查询:SELECT 的求值顺序
SQL 书写顺序与逻辑执行顺序并不一致,理解后者是写好查询的关键:
这解释了为什么 WHERE 中不能使用 SELECT 定义的别名,而 ORDER BY 可以。
连接(JOIN)
聚合与分组
WHERE 过滤分组前的行,HAVING 过滤分组后的聚合结果,二者不可混用。
子查询与 CTE
窗口函数
窗口函数在不折叠行的前提下做组内计算,常用于排名、累计与同环比:
Tip
窗口函数的关键在于 OVER (PARTITION BY ... ORDER BY ...):PARTITION BY 划分窗口,ORDER BY 定义窗口内顺序。它与 GROUP BY 最大的区别是不减少结果行数。
参数化查询
无论使用哪种语言访问数据库,都应使用参数占位符,交由驱动做安全转义:
Warning
严禁用字符串拼接构造 SQL(如 fmt.Sprintf("... WHERE name = '%s'", name)),这会引入 SQL 注入漏洞。占位符在 MySQL 中为 ?,在 PostgreSQL 中为 $1、$2。
小结
- 记住 SELECT 的逻辑执行顺序,能解释大多数「为什么别名不能用」的问题。
- 连接会放大行数,聚合前想清楚粒度(一行代表什么)。
WHERE与HAVING分工明确;CTE 与窗口函数让复杂查询保持可读。- 一律使用参数化查询,杜绝 SQL 注入。