在ORDER BY子句中转换列别名

时间:2014-08-27 13:41:13

标签: sql postgresql casting sql-order-by

鉴于此:

CREATE TABLE test (
  a int,
  b varchar(255)
);

INSERT INTO test VALUES(1, '100');
INSERT INTO test VALUES(1, '50');
INSERT INTO test VALUES(1, '075');
INSERT INTO test VALUES(1, '+50');
INSERT INTO test VALUES(1, '-50');

SELECT a, b AS c
FROM test AS t
ORDER BY t.a, c;

SELECT a, b AS c
FROM test AS t
ORDER BY t.a, t.b::int;

SELECT a, b AS c
FROM test AS t
ORDER BY t.a, c::int;

最后一个查询返回错误:
ERROR: column "c" does not exist: SELECT a, b AS c FROM test AS t ORDER BY t.a, c::int

我想订购列别名给出的结果 如果我还想要转换由别名给出的特定列,则它不起作用。

ORDER BY alias工作的原因是什么,ORDER BY alias::int不是?{ 是否有另一种方法在转换中使用列别名?

2 个答案:

答案 0 :(得分:2)

这是一个很长的评论。

Here是对此问题的早期参考,我引用它:

  

ORDER BY(以及GROUP BY)允许引用输出列名   只有当他们 unadorned 时。你不能在表达式中使用它们。

如果我不得不推测其原因,那将与表达式评估有关。我认为Postgres引擎逻辑上会将您的查询重写为:

SELECT a, b AS c, c::int as INVISIBLEUNSEENCOLUMN
FROM test AS t
ORDER BY t.a, INVISIBLEUNSEENCOLUMN;

也就是说,它将表达式移动到通常计算表达式的位置(在编译代码中称为“select”节点)。好吧,这会产生已知的列错误,因为该代码不能理解在同一级别定义的别名。当我想在查询中使用列别名时,我经常使用子查询,以避免混淆。

解决问题很容易:使用子查询,使用order by中的原始列名,或在select中包含强制转换值。

答案 1 :(得分:0)

这是由于SQL和Select子句中的事件序列造成的;提供列别名的是最后一个

1: FROM
2: the JOINS
3: WHERE clause
4: GROUP BY clause
5: HAVING clause
6: SELECT clause
7: ORDER BY clause

ORDER BY是最后一个,因此在该阶段执行了SELECT子句,然后列别名可用于ORDER BY。

但是,执行select子句之前的所有子句都不了解列别名。


大多数解决方法," nest"查询,例如

select col_alias from ( select x as col_alias from y ) 

编辑:我所知道的唯一例外是产品Teradata (可能还有其他人,但我已经使用了很多)