如果我在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'
(即按常量字符串排序)?这种行为可以通过设置来改变吗?
3条答案
按热度按时间zc0qhyus1#
这是MySQL中一个不幸的二义性。列别名可以用标识符语法或字符串文字语法定义。这在https://dev.mysql.com/doc/refman/8.0/en/problems-with-alias.html中有描述。
在MySQL中,双引号和单引号默认是一样的,都是string literal分隔符。
这是MySQL中的字符串文字语法:
这是MySQL中的标识符语法:
但是当你到达
ORDER BY
时,你必须使用标识符。如果你按字符串文字排序,那么它就算作一个常量值。按常量值排序会导致所有行的平局,所以顺序最终是任何行被读取的顺序,而不是你想要的顺序。可以通过更改SQL模式使双引号充当标识符分隔符。
这个错误是意料之中的,这只是为了说明在我更改SQL模式后,
abc
被视为标识符而不是字符串。当然,您可以通过将其放在
my.cnf
文件中来使SQL模式的更改持久化(不是CONCAT()用法,而是使用其他适当的SQL模式来拼写整个SQL模式字符串):xqk2d5yq2#
双引号内的字符串被视为字符串,而不是列别名。
当列别名中有特殊字符(如空格)时,请使用反引号。
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