我的 MySQL 似乎不使用 ” 作为 ORDER BY 子句中的字段引号?

huangapple go评论62阅读模式
英文:

My MySQL doesn't seem to use " as field quotes in the ORDER BY clause?

问题

If I run the following query in MySQL 8.0.28:

SELECT 2 as "A A"
UNION ALL
SELECT 1 

ORDER BY "A A"

I get

A A
2
1

If I run

SELECT 2 as "A A"
UNION ALL
SELECT 1 

ORDER BY `A A`

I get

A A
1
2

like I expect.

Does it mean MySQL doesn't use "double quoted fields" in the ORDER BY, and my ORDER BY "A A" is being interpreted as if it were ORDER BY 'A A' (i.e. order by constant string)? Can this behavior be altered by a setting?

英文:

If I run the folowing query in MySQL 8.0.28:

SELECT 2 as "A A"
UNION ALL
SELECT 1 

ORDER BY "A A"

I get

A A
2
1

If I run

SELECT 2 as "A A"
UNION ALL
SELECT 1 

ORDER BY `A A`

I get

A A
1
2

like I expect.

Does it mean MySQL doesn't use "double quoted fields" in the ORDER BY, and my ORDER BY "A A" is being interpreted as if it were ORDER BY 'A A' (i.e. order by constant string)? Can this behavior be altered by a setting?

答案1

得分: 1

双引号内的字符串被视为字符串,而不是列别名。

在列别名中含有特殊字符(如空格)时,请使用反引号。

英文:

Strings inside double quotes are treated as strings, not as a column alias.

Use backticks when you have special charcters (like spaces) in the column aliases.

答案2

得分: 1

在MySQL中,双引号用于包围字符串文字,而反引号用于包围标识符,如列名和表名。

由于反引号提供了额外的安全性,它们在程序生成的SQL语句中被广泛使用,其中标识符名称可能事先不知道。

许多其他数据库系统在这些特殊名称周围使用双引号(")。为了可移植性,您可以在MySQL中启用ANSI_QUOTES模式,并使用双引号而不是反引号来限定标识符名称。

更多详情请查看:反引号

英文:

In MySQL, double quotes are using to enclose string literals, whereas backticks are used to enclose identifiers such as column names ,table names.

Since the backticks provide an extra level of safety, they are used extensively in program-generated SQL statements, where the identifier names might not be known in advance.

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.

for more detail: backticks

答案3

得分: 1

这是MySQL中的一个不幸的歧义。列别名可以使用标识符语法或字符串文字语法定义。这在 https://dev.mysql.com/doc/refman/8.0/en/problems-with-alias.html 中有描述。

在MySQL中,默认情况下,双引号与单引号相同。它们都是字符串文字分隔符。

这是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文件中(不是CONCAT()使用,而是用其他适当的SQL模式拼写整个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

英文:

This is an unfortunate ambiguity in MySQL. Column aliases can be defined either with identifier syntax or by string literal syntax. This is described in https://dev.mysql.com/doc/refman/8.0/en/problems-with-alias.html

By default in MySQL, double-quotes are the same as single-quotes by default. They are both string literal delimiters.

This is string literal syntax in MySQL:

SELECT 2 as "A A"
...

This is identifier syntax in MySQL:

SELECT 2 as `A A`
...

But when you reach the ORDER BY, you must use identifiers. If you order by a string literal, then it counts as a constant value. Sorting by a constant value results in a tie for all rows, so the order ends up being whatever order the rows were read in, not the order you wanted.

You can make double-quotes act as identifier delimiters by changing the SQL mode.

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'

The error is expected, this is just to demonstrate that abc is treated as an identifier instead of a string after I changed the SQL mode.

You can of course make the change to SQL mode persistent by putting it in your my.cnf file (not the CONCAT() usage but spell out the whole SQL mode string with other appropriate SQL modes):

[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

huangapple
  • 本文由 发表于 2023年4月17日 20:01:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/76034943.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定