SQL 的 ORDER BY 是每个开发者都熟悉的语法,但很少有人知道它经历了怎样的演进。Markus Winand 在 recent article 中梳理了 ORDER BY 从诞生到现代的发展历程,揭示了这个看似简单的语法背后的复杂性。

在 SQL 的早期版本中,ORDER BY 的能力相当有限。它只能对 SELECT 列表中的列进行排序,而且排序的顺序是固定的——没有升序降序的明确指定,默认行为在不同数据库间差异很大。更关键的是,当时 ORDER BY 的语义并不清晰:它在逻辑上是在 SELECT 之后执行的,但实际执行顺序往往不同。这种逻辑顺序与实际执行顺序的差异,是理解 SQL 行为的关键。
到了 SQL:1999 标准,一个重要的改变是引入了位置引用——可以用数字指定排序的列,比如 ORDER BY 1, 2。但这个特性很快被发现容易出错——当 SELECT 列表变化时,位置引用可能指向完全不同的列。因此这个特性在后续标准中被移除,SQL:2003 之后不再允许这种写法。
另一个重要演进是对 NULL 值的排序处理。在 SQL 标准中,NULL 被定义为"未知",因此 NULL 与 NULL 之间、NULL 与非 NULL 之间的大小关系都是未定义的。这导致了一个问题:在 ORDER BY 时,NULL 应该放在开头还是结尾?不同的数据库有不同的默认行为。SQL:2008 引入的 NULLS FIRST 和 NULLS LAST 语法解决了这个问题,让开发者可以明确指定 NULL 值的排序位置。
SQL:2008 还引入了另一个重要特性:在子查询中使用 ORDER BY。这个特性在早期是被禁止的,因为子查询的结果集被认为是无序的。但实际需求推动了标准的演进——当需要 TOP N 查询时,必须在子查询中指定排序顺序。这个需求的满足体现了 SQL 标准与现实需求之间的互动。
从这些演进可以看出,SQL 标准的设计并非一成不变,而是在实际使用中不断调整和完善。理解这些历史背景有助于开发者避免常见的陷阱。比如,知道 ORDER BY 的位置引用已被废弃,就不应该在新代码中使用它;知道 NULL 的排序行为在不同数据库间可能有差异,就应该在需要时显式使用 NULLS FIRST 或 NULLS LAST。
更重要的是,这些演进提醒我们:SQL 标准规定的是"逻辑评估顺序",而不是"实际执行顺序"。数据库优化器有权在保证结果正确的前提下重新排列操作顺序,只要最终结果符合逻辑顺序的要求。这是现代数据库能够高效执行复杂查询的关键之一。
来源:Modern SQL (https://modern-sql.com/blog/2026-05/order-by-history)