不能在 mysql 函数中使用别名作为 ORDER BY 子句的一部分
Can't use alias in mysql function as part of ORDER BY clause
如果我执行以下查询,它工作正常。
SELECT
CASE WHEN description LIKE '%a%' THEN 'A'
WHEN description LIKE '%b%' THEN 'B'
ELSE 'C'
END AS foo
,COUNT(*) AS cnt
FROM product p
GROUP BY foo
ORDER BY foo;
结果类似于
foo | cnt
-----------
A | 809
B | 29
C | 55
但是,下面的查询给出了一个错误。请注意,我只更改了最后一行。
SELECT
CASE WHEN description LIKE '%a%' THEN 'A'
WHEN description LIKE '%b%' THEN 'B'
ELSE 'C'
END AS foo
,COUNT(*) AS cnt
FROM product p
GROUP BY foo
ORDER BY FIELD(foo, 'A', 'B', 'C'); -- Different line
SQL Error (1054): Unknown column 'foo' in 'order clause'
这是为什么?
我正在使用 MySQL 版本 5.0.22
更新:
只是为了扩展,如果我省略分组,我会看到相同的行为,即:
SELECT
CASE WHEN description LIKE '%a%' THEN 'A'
WHEN description LIKE '%b%' THEN 'B'
ELSE 'C'
END AS foo
FROM product p
ORDER BY foo;
(运行良好)
对
SELECT
CASE WHEN description LIKE '%a%' THEN 'A'
WHEN description LIKE '%b%' THEN 'B'
ELSE 'C'
END AS foo
FROM product p
ORDER BY FIELD(foo, 'A', 'B', 'C'); -- Different line
(错误)
如果您想按别名分组,请将您的查询放入派生的 table
SELECT foo, count(*) cnt FROM (
SELECT
CASE WHEN description LIKE '%a%' THEN 'A'
WHEN description LIKE '%b%' THEN 'B'
ELSE 'C'
END AS foo
FROM product p
) t1
GROUP BY foo
ORDER BY FIELD(foo, 'A', 'B', 'C'); -- Different line
您的错误发生是因为您不能在 field
方法中使用别名。
使用 1
而不是 foo
。像这样:
ORDER BY FIELD(1, 'A', 'B', 'C'); -- Different line
如果您知道顺序位置,您应该能够按顺序分组,例如..
select *
from
( SELECT
CASE WHEN description LIKE '%a%' THEN 'A'
WHEN description LIKE '%b%' THEN 'B'
ELSE 'C' END AS foo
,COUNT(*) AS cnt
FROM product p
GROUP BY 1 ) PreQuery
ORDER BY
FIELD(foo, 'A', 'B', 'C');
我知道 order by 可能不起作用,因为它是函数的一部分,所以我将其包装了......或者,您只需要让动态构造的查询构建 case/when 条件,然后将它粘贴到每个组件中
SELECT
CASE WHEN description LIKE '%a%' THEN 'A'
WHEN description LIKE '%b%' THEN 'B'
ELSE 'C' END AS foo
,COUNT(*) AS cnt
FROM
product p
GROUP BY
CASE WHEN description LIKE '%a%' THEN 'A'
WHEN description LIKE '%b%' THEN 'B'
ELSE 'C' END
ORDER BY
FIELD( CASE WHEN description LIKE '%a%' THEN 'A'
WHEN description LIKE '%b%' THEN 'B'
ELSE 'C' END, 'A', 'B', 'C');
发生这种情况的原因是因为 MySQL 在早期版本(显然包括 5.0)中处理 ORDER BY 的方式如下:
如果整个ORDER BY
子句是整数,则按projection子句对应的元素排序(ORDER BY 2
按project子句的第二个元素排序)
如果整个 ORDER BY
子句是标识符,则搜索具有此类别名的投影列表元素,或者,如果 none 找到,则搜索具有此类别名的列名称,并以此排序。
否则,解析表达式。解析过程中只有列名可见,别名不可见。
所以在你的第一个查询中你得到了第二种情况,因此你看到了别名,在你的第二个查询中你得到了第三种情况,因此看不到它。
更新:似乎 PostgreSQL 具有完全相同的行为。在这里查看 Peter Eisentraut 的回答
[ ORDER BY Alias not working ]
他总结了我所说的相同内容,但针对的是 PostgreSQL。 Order By 可以有一个别名(输出列),或者一个整数,或者一个引用输入列.
的表达式
如果我执行以下查询,它工作正常。
SELECT
CASE WHEN description LIKE '%a%' THEN 'A'
WHEN description LIKE '%b%' THEN 'B'
ELSE 'C'
END AS foo
,COUNT(*) AS cnt
FROM product p
GROUP BY foo
ORDER BY foo;
结果类似于
foo | cnt
-----------
A | 809
B | 29
C | 55
但是,下面的查询给出了一个错误。请注意,我只更改了最后一行。
SELECT
CASE WHEN description LIKE '%a%' THEN 'A'
WHEN description LIKE '%b%' THEN 'B'
ELSE 'C'
END AS foo
,COUNT(*) AS cnt
FROM product p
GROUP BY foo
ORDER BY FIELD(foo, 'A', 'B', 'C'); -- Different line
SQL Error (1054): Unknown column 'foo' in 'order clause'
这是为什么?
我正在使用 MySQL 版本 5.0.22
更新:
只是为了扩展,如果我省略分组,我会看到相同的行为,即:
SELECT
CASE WHEN description LIKE '%a%' THEN 'A'
WHEN description LIKE '%b%' THEN 'B'
ELSE 'C'
END AS foo
FROM product p
ORDER BY foo;
(运行良好)
对
SELECT
CASE WHEN description LIKE '%a%' THEN 'A'
WHEN description LIKE '%b%' THEN 'B'
ELSE 'C'
END AS foo
FROM product p
ORDER BY FIELD(foo, 'A', 'B', 'C'); -- Different line
(错误)
如果您想按别名分组,请将您的查询放入派生的 table
SELECT foo, count(*) cnt FROM (
SELECT
CASE WHEN description LIKE '%a%' THEN 'A'
WHEN description LIKE '%b%' THEN 'B'
ELSE 'C'
END AS foo
FROM product p
) t1
GROUP BY foo
ORDER BY FIELD(foo, 'A', 'B', 'C'); -- Different line
您的错误发生是因为您不能在 field
方法中使用别名。
使用 1
而不是 foo
。像这样:
ORDER BY FIELD(1, 'A', 'B', 'C'); -- Different line
如果您知道顺序位置,您应该能够按顺序分组,例如..
select *
from
( SELECT
CASE WHEN description LIKE '%a%' THEN 'A'
WHEN description LIKE '%b%' THEN 'B'
ELSE 'C' END AS foo
,COUNT(*) AS cnt
FROM product p
GROUP BY 1 ) PreQuery
ORDER BY
FIELD(foo, 'A', 'B', 'C');
我知道 order by 可能不起作用,因为它是函数的一部分,所以我将其包装了......或者,您只需要让动态构造的查询构建 case/when 条件,然后将它粘贴到每个组件中
SELECT
CASE WHEN description LIKE '%a%' THEN 'A'
WHEN description LIKE '%b%' THEN 'B'
ELSE 'C' END AS foo
,COUNT(*) AS cnt
FROM
product p
GROUP BY
CASE WHEN description LIKE '%a%' THEN 'A'
WHEN description LIKE '%b%' THEN 'B'
ELSE 'C' END
ORDER BY
FIELD( CASE WHEN description LIKE '%a%' THEN 'A'
WHEN description LIKE '%b%' THEN 'B'
ELSE 'C' END, 'A', 'B', 'C');
发生这种情况的原因是因为 MySQL 在早期版本(显然包括 5.0)中处理 ORDER BY 的方式如下:
如果整个
ORDER BY
子句是整数,则按projection子句对应的元素排序(ORDER BY 2
按project子句的第二个元素排序)如果整个
ORDER BY
子句是标识符,则搜索具有此类别名的投影列表元素,或者,如果 none 找到,则搜索具有此类别名的列名称,并以此排序。否则,解析表达式。解析过程中只有列名可见,别名不可见。
所以在你的第一个查询中你得到了第二种情况,因此你看到了别名,在你的第二个查询中你得到了第三种情况,因此看不到它。
更新:似乎 PostgreSQL 具有完全相同的行为。在这里查看 Peter Eisentraut 的回答 [ ORDER BY Alias not working ]
他总结了我所说的相同内容,但针对的是 PostgreSQL。 Order By 可以有一个别名(输出列),或者一个整数,或者一个引用输入列.
的表达式