别名不在ORDER BY子句中工作

时间:2012-11-05 11:26:28

标签: mysql sql sql-order-by case

这在MySQL 5中可以正常工作:

SELECT INSTR(foo, 'Bar') as foobar
FROM Table
ORDER BY CASE WHEN foobar = 1 THEN foo END DESC;

在MySQL 4中,我收到错误:

ERROR 1054 (42S22): Unknown column 'foobar' in 'order clause'

但是,如果我将条款更改为此,它将适用于两个版本:

SELECT INSTR(foo, 'Bar') as foobar
FROM Table
ORDER BY CASE WHEN INSTR(foo, 'Bar') = 1 THEN foo END DESC;

为确保兼容性,我是否必须始终使用第二种方式?

3 个答案:

答案 0 :(得分:1)

因为foobar是别名。除非它来自派生查询(子查询),否则它不是列。如下所示

SELECT * 
FROM
(
   SELECT INSTR(foo, 'Bar') as foobar
   FROM Table
) a
ORDER BY CASE WHEN foobar = 1 THEN foo END DESC;

答案 1 :(得分:1)

基本上,您不能在相同的“查询级别”重用列别名。

如果你想编写兼容/可移植的SQL并且不想重复函数调用,那么通常的方法就是将查询包装到派生表中。

select *
from (
  SELECT INSTR(foo, 'Bar') as foobar,
         foo
  FROM Table
) t
ORDER BY CASE WHEN foobar = 1 THEN foo END DESC;

请注意,您需要在内部查询内的“外部”查询中包含要使用的任何列。如果省略内部派生表中的列foo,则可以在外层访问它。

答案 2 :(得分:1)

根据其他答案,您无法在CASE中使用别名 您可以直接在INSTR()中使用CASE,而不是使用子查询:

SELECT INSTR(foo, 'Bar') as foobar
FROM Table
ORDER BY CASE WHEN INSTR(foo, 'Bar') = 1 THEN foo END DESC;

当您使用子查询时,请注意您还必须选择foo列进行排序,否则您将收到错误like this

所以你的子查询查询应该是:

SELECT * FROM
(
    SELECT foo,INSTR(foo, 'Bar') as foobar
    FROM t
) A
ORDER BY CASE WHEN foobar = 1 THEN foo END DESC;