我的MySQL似乎没有在ORDER BY子句中使用“作为字段引号?

z31licg0  于 2023-04-19  发布在  Mysql
关注(0)|答案(3)|浏览(117)

如果我在MySQL 8.0.28中运行以下查询:

SELECT 2 as "A A"
UNION ALL
SELECT 1 

ORDER BY "A A"

我明白
| A A|
| --------------|
| 二|
| 1|
如果我逃跑

SELECT 2 as "A A"
UNION ALL
SELECT 1 

ORDER BY `A A`

我明白
| A A|
| --------------|
| 1|
| 二|
和我想的一样
这是否意味着MySQL在ORDER BY中不使用“双引号字段”,并且我的ORDER BY "A A"被解释为好像它是ORDER BY 'A A'(即按常量字符串排序)?这种行为可以通过设置来改变吗?

zc0qhyus

zc0qhyus1#

这是MySQL中一个不幸的二义性。列别名可以用标识符语法或字符串文字语法定义。这在https://dev.mysql.com/doc/refman/8.0/en/problems-with-alias.html中有描述。
在MySQL中,双引号和单引号默认是一样的,都是string literal分隔符。
这是MySQL中的字符串文字语法:

SELECT 2 as "A A"
...

这是MySQL中的标识符语法:

SELECT 2 as `A A`
...

但是当你到达ORDER BY时,你必须使用标识符。如果你按字符串文字排序,那么它就算作一个常量值。按常量值排序会导致所有行的平局,所以顺序最终是任何行被读取的顺序,而不是你想要的顺序。
可以通过更改SQL模式使双引号充当标识符分隔符。

mysql> select "abc";
+-----+
| abc |
+-----+
| abc |
+-----+

mysql> set sql_mode = concat(@@sql_mode, ',ANSI_QUOTES');
Query OK, 0 rows affected (0.00 sec)

mysql> select "abc";
ERROR 1054 (42S22): Unknown column 'abc' in 'field list'

这个错误是意料之中的,这只是为了说明在我更改SQL模式后,abc被视为标识符而不是字符串。
当然,您可以通过将其放在my.cnf文件中来使SQL模式的更改持久化(不是CONCAT()用法,而是使用其他适当的SQL模式来拼写整个SQL模式字符串):

[mysqld]
sql_mode = ANSI_QUOTES,ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
xqk2d5yq

xqk2d5yq2#

双引号内的字符串被视为字符串,而不是列别名。
当列别名中有特殊字符(如空格)时,请使用反引号。

zaq34kh6

zaq34kh63#

在MySQL中,双引号用于括起字符串文字,而反引号用于括起列名,表名等标识符。
由于反引号提供了额外的安全级别,因此它们广泛用于程序生成的SQL语句中,其中可能事先不知道标识符名称。
Many other database systems use double quotation marks (") around such special names. For portability, you can enable ANSI_QUOTES mode in MySQL and use double quotation marks instead of backticks to qualify identifier names.
更多详情:backticks

相关问题