简体   繁体   English

在ORDER BY子句中强制转换列别名

[英]Casting column alias in ORDER BY clause

Given this: 鉴于这种:

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;

The last query returns the error: 最后一个查询返回错误:
ERROR: column "c" does not exist: SELECT a, b AS c FROM test AS t ORDER BY ta, c::int

I want to order a result given by a column alias. 我想订购由列别名给出的结果。
If I additionally want to cast a specific column given by an alias it does not work. 如果我还想转换由别名给定的特定列,则它不起作用。

What is the reason for ORDER BY alias is working and ORDER BY alias::int is not? ORDER BY alias正常工作而ORDER BY alias::int不正常的原因是什么?
Is there another way to use column aliases in a cast? 还有另一种在转换中使用列别名的方法吗?

This is a big long for a comment. 这是一个很长的评论期。

Here is an early reference to this issue, from which I quote: 是对此问题的早期参考,引用其中:

ORDER BY (and also GROUP BY ) permit references to output column names only when they are unadorned . ORDER BY (以及GROUP BY )仅在未修饰时允许对输出列名称的引用。 You cannot use them in expressions. 您不能在表达式中使用它们。

If I had to speculate on the reasons for this, it would have to do with expression evaluation. 如果我不得不推测其原因,则与表达式评估有关。 I think the Postgres engine logically rewrites your query to be something like: 我认为Postgres引擎在逻辑上将您的查询重写为:

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

That is, it moves the expression to where expressions are usually evaluated (into what I might call the "select" node in the compiled code). 也就是说,它将表达式移动到通常对表达式求值的位置(在编译后的代码中可以称为“选择”节点)。 Well, this generates the known column error, because that code doesn't understand aliases defined at the same level. 好的,这会产生已知的列错误,因为该代码无法理解在同一级别定义的别名。 When I want to use column aliases in a query, I often use subqueries, to avoid any confusion. 当我想在查询中使用列别名时,我经常使用子查询,以避免任何混乱。

It is easy enough to work around the problem: use a subquery, use the original column name in the order by , or include the cast value in the select . 解决该问题很容易:使用子查询, order by使用原始列名,或在select包含强制转换值。

This is due to the sequence of events in SQL and the Select clause; 这是由于SQL中的事件顺序和Select子句所致; where column aliases are provided, is second last 提供列别名的位置是倒数第二

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

ORDER BY is the last so by that stage the SELECT clause has been executed and column aliases are then available to ORDER BY. ORDER BY是最后一个,因此在该阶段已执行SELECT子句,然后列别名可用于ORDER BY。

However, all clauses prior to the execution of the select clause don't understand the column aliases. 但是,执行select子句之前的所有子句都不了解列别名。


most workaround workaround, "nest" the query, eg 大多数解决方法,“嵌套”查询,例如

select col_alias from ( select x as col_alias from y ) 

EDIT: the only exception to this that I know of is in the product Teradata (there may be others but I've used many) 编辑:我所知道的唯一例外是在产品Teradata中(可能还有其他,但我使用了很多)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM