PostgreSQL - 为什么我不能按列的函数排序?



我正在尝试一些我认为应该相对简单的东西(它适用于Oracle和MySQL(。下面代码的PostgreSQL fiddle在这里可用——只需更改服务器即可查看其他代码。

非常简单的测试用例:

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);

如前所述,这适用于Oracle和MySQL,但不适用于PostgreSQL、Firebird和SQL Server。

有人能解释一下原因吗?导致ORDER BY失败的列的一个简单函数是什么?这似乎与这里的手册相冲突,手册上写着:

排序表达式可以是在查询的选择列表。一个例子是:

从表1中选择a,b ORDER BY a+b,c;

只有输入列可以在表达式中使用,而不是在文档中指定的简单列名中:

每个表达式可以是输出列(SELECT列表项(的名称或序号,也可以是由输入列值形成的任意表达式。

另请阅读此注释:

在SQL-92标准中,ORDERBY子句只能使用输出列名或数字,而GROUP BY子句只能使用基于输入列名的表达式。PostgreSQL扩展了这些子句中的每一个,以允许其他选择(但如果存在歧义,它会使用标准的解释(。PostgreSQL还允许这两个子句指定任意表达式。请注意,表达式中出现的名称将始终作为输入列名,而不是输出列名。

如果您仔细阅读文档,它指出别名或列输出名称不能按子句的顺序在表达式中使用。

注意,输出列名必须是独立的,也就是说,它不能用于表达式

从表1中选择a+b作为sum,c ORDER BY sum+c;--错误的

所以,你需要

SELECT
y AS the_char
FROM 
x
ORDER BY ASCII(y);

输出列名称(作为the_char(只能用作ORDER BY子句中的普通值,而不能用作表达式的一部分;另一方面,y可以在用于排序的表达式中自由使用。你可以做:

select y as the_char
from x
order by ascii(y)

或者,您可以使用子查询来更改输出列the_char的范围,以便将其作为真正的列进行管理和处理。例如:

select *
from (
select y as the_char from x
) z
order by ascii(the_char)

最新更新