PostgreSQL为何无法对列的函数结果使用ORDER BY?
为何PostgreSQL中ORDER BY对别名使用函数会报错?
我尝试实现一个原本以为很简单的功能,该功能在Oracle和MySQL中可正常运行,但在PostgreSQL、Firebird和SQL Server中无法运行。
极简测试案例
建表语句:
CREATE TABLE x ( y CHAR(1) );
插入数据:
INSERT INTO x VALUES ('x');
INSERT INTO x VALUES('y');
两种查询情况
正常运行的查询
执行以下语句可正常返回预期结果:
SELECT y AS the_char FROM x ORDER BY the_char;
结果:
the_char x y
报错的查询
但执行以下语句时会报错:
SELECT y AS the_char FROM x ORDER BY ASCII(the_char);
错误信息:
ERROR: column "the_char" does not exist LINE 5: ORDER BY ASCII(the_char);
原因解释
这是因为不同数据库对SQL标准的实现和扩展存在差异:
- SQL标准规定:
ORDER BY子句可以直接引用SELECT列表中的输出列别名,但不允许将别名作为表达式的一部分(比如嵌套进函数)来使用。PostgreSQL、Firebird、SQL Server严格遵循了这一标准,因此会认为the_char不是实际存在的列,只是别名,无法在ASCII()函数中使用。 - Oracle和MySQL的扩展:这两个数据库做了语法扩展,允许在
ORDER BY的表达式中直接使用SELECT列表的别名,相当于自动将别名替换为对应的原始表达式(即把ASCII(the_char)解析为ASCII(y))。
关于你提到的PostgreSQL官方文档说明:
排序表达式可以是查询SELECT列表中有效的任意表达式。示例如下:
SELECT a, b FROM table1 ORDER BY a + b, c;
这里的描述并没有冲突,文档指的是你可以将SELECT列表中原本的表达式直接放到ORDER BY里(比如示例中的a + b就是合法的表达式,或者如果SELECT里有a+b AS sum,你也可以写ORDER BY a+b),而不是允许将别名代入到新的表达式中使用。
内容的提问来源于stack exchange,提问作者Vérace
相关产品推荐
相关产品推荐

