Can';t在mysql函数中使用别名作为ORDERBY子句的一部分
如果我执行下面的查询,它就可以正常工作Can';t在mysql函数中使用别名作为ORDERBY子句的一部分,mysql,sql,sql-order-by,Mysql,Sql,Sql 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
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错误(1054):“order子句”中的未知列“foo”
为什么呢
我正在考虑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;
(运行良好)
vs
(错误)如果要按别名分组,请将查询放入派生表中
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
发生错误的原因是无法在
字段中使用别名
使用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的方式如下:
如果整个orderby
子句是一个整数,则按投影子句的相应元素排序(orderby 2
按项目子句的第二个元素排序)
如果整个ORDER BY
子句是一个标识符,则搜索具有此类别名的投影列表元素,如果未找到,则搜索具有此类名称的列,并按其排序
否则,解析表达式。在解析过程中,只有列名可见,而别名不可见
因此,在第一次查询中,您将看到第二种情况,因此您可以看到别名;在第二次查询中,您将看到第三种情况,因此您无法看到别名
更新:似乎PostgreSQL具有完全相同的行为。请看彼得·艾森特的回答
[]
他总结了和我说的一样的东西,只是为了PostgreSQL。Order By可以有别名(输出列),也可以是整数,或者是引用输入列的表达式我知道这种可能性,但所讨论的查询(比我发布的示例更复杂)是通过友好方式生成的,因此,我不能像那样改变它的结构,而不对生成它的代码进行大量工作。在这种情况下,1
当然是一个整数1,而不是投影的第一个元素。我可以在MySQL 5.6中运行精确的查询。您使用的是什么版本的MySQL?谢谢!在MySQL文档中,我找不到任何地方有明确的声明。我知道这一点,因为我以前玩过MySQL代码,并在其中看到了这种行为。
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');