SQL 作为一种声明式查询语言,与 C、Python 等过程式 / 面向对象语言的设计目标不同,存在一些不符合传统编程习惯的语法特性。以下是常见的 “反直觉” 设计及其对比分析:
目录
一、语法符号与基础规则差异
1.代码块与作用域标识
- SQL:无
{}或缩进标识代码块,存储过程等复杂逻辑通过关键字(如BEGIN...END)界定,作用域依赖全局 / 会话级变量。 - C/Python:用
{}(C)或缩进(Python)明确代码块边界,变量遵循块级作用域(如if/for代码块内声明的变量无法外部访问)。
2.等号 = 的双重语义
- MySQL 在存储过程内兼容
:= 和 = 两种赋值方式,但会话变量(@var)仅支持 = 赋值,查询中赋值必须用 := (SELECT @count := COUNT(*) FROM users;)。 = 也用于比较(如WHERE age = 18)。 - 标准 SQL 及 Oracle、SQL Server 等数据库在赋值时需用
:=(如 Oracle PL/SQL 中var := 10),=仅用于比较。 - C/Python:赋值用
=,比较用==,严格区分。 - 反直觉点:容易混淆赋值和比较操作,尤其在条件语句中。
2.类型灵活性
- SQL:支持隐式类型转换(如数字与字符串比较时自动转换,
WHERE age = '18'等效于age = 18)。 - Python:强类型语言,不同类型(如
int与str)直接比较会报错。
3. 逻辑顺序与执行顺序不一致
-
书写顺序:
SELECT → FROM → WHERE → GROUP BY → HAVING → ORDER BY -
执行顺序:
FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BYSELECT name, COUNT(*) FROM users WHERE age > 18 GROUP BY name HAVING COUNT(*) > 5 ORDER BY name DESC;
二、 三值逻辑(TRUE/FALSE/NULL)
- SQL:SQL 中
NULL代表 “未知值”,而非 “空值”,任何与NULL的比较返回NULL(且任何涉及NULL的运算(如NULL + 10)返回NULL)。 - C/Python:逻辑运算仅返回
True或False,None需显式判断。 - 修正:必须用
IS NULL或COALESCE处理。
三、集合操作
- SQL:面向集合操作,无需显式循环。
-- SQL:批量更新所有用户年龄 UPDATE users SET age = age + 1; - C/Python:需显式遍历(如
for循环)。# Python:逐行处理,低效 for user in users: user.age += 1 - 反直觉点:习惯过程式编程的开发者难以理解 “无循环” 逻辑。
四、字符串处理与函数命名
1. 字符串拼接语法不统一
- SQL:不同数据库用不同操作符(如
+、||、CONCAT())。-- MySQL SELECT CONCAT(first_name, ' ', last_name) AS full_name; -- SQL Server SELECT first_name + ' ' + last_name AS full_name; - Python:统一用
+或join()。
2. 函数命名不一致
- SQL:不同数据库函数名差异大(如
SUBSTRINGvsSUBSTR)。-- MySQL SELECT SUBSTRING('hello', 1, 3); -- 结果:hel -- Oracle SELECT SUBSTR('hello', 1, 3); -- 结果:hel
五、总结
SQL 的 “反直觉” 特性源于其声明式范式和面向集合的设计理念,与过程式语言(如 C/Python)的核心差异包括:
- 声明式 vs 过程式:SQL 只需描述 “要什么”,无需指定 “怎么做”。
- 集合操作优先:避免显式循环,通过集合运算高效处理数据。
- NULL 哲学:基于关系型数据库理论,
NULL代表数据缺失的不确定性。 - 历史兼容性:保留早期语法(如隐式 JOIN)导致规则不一致。

400

被折叠的 条评论
为什么被折叠?



