【问题标题】:Aliases not working in ORDER BY clause别名在 ORDER BY 子句中不起作用
【发布时间】:2012-11-05 11:26:27
【问题描述】:

这在 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;

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

【问题讨论】:

标签: mysql sql sql-order-by case


【解决方案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】:

因为foobar 是一个别名。它不是一个列,除非它来自派生查询(子查询)。就像下面的这个

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

【讨论】:

    【解决方案3】:

    根据其他答案,您不能在 CASE 中使用别名。
    您可以直接在CASE 中使用INSTR() 而不是使用子查询,如下所示:

    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;
    

    【讨论】:

    • 谢谢,但我已经有了这个解决方案,我认为这可能是一个更好的方法。其他答案涵盖了为什么我不能重用foobar
    • @ViniciusMassuchetto 很好:)。但请参阅更新的答案以获取更多说明。
    猜你喜欢
    • 1970-01-01
    • 2011-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多