为啥在 MySQL 查询中添加 '*' 会导致语法错误?

Posted

技术标签:

【中文标题】为啥在 MySQL 查询中添加 \'*\' 会导致语法错误?【英文标题】:Why does adding '*' to a MySQL query cause a syntax error?为什么在 MySQL 查询中添加 '*' 会导致语法错误? 【发布时间】:2011-10-27 20:53:38 【问题描述】:

mysql 中,这段代码可以正常工作:

select f, blegg.* from blegg limit 1;

+------+------+------+------+
| f    | f    | g    | h    |
+------+------+------+------+
|   17 |   17 |    2 |   17 |
+------+------+------+------+
1 row in set (0.00 sec)

那么为什么这段代码会导致语法错误呢?

select f, * from blegg limit 1;

-- * is unqualified
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use near '* 
from blegg limit 1' at line 1

我浏览了手册,但没有真正找到任何东西。为什么select <field>, * ... 失败而select <field>, <table>.* ...select * ...select *, <field> ... 成功?

【问题讨论】:

我无法解释为什么。但我知道甲骨文也在做同样的事情。 【参考方案1】:

MySQL 手册在SELECT syntax 部分非常清楚地列出了所有这些内容:

仅由一个不合格的* 组成的选择列表可用作 从所有表中选择所有列的速记:

SELECT * FROM t1 INNER JOIN t2 ...

tbl_name.* 可以用作 从命名表中选择所有列的合格速记:

SELECT t1.*, t2.* FROM t1 INNER JOIN t2 ...

使用不合格的* 选择列表中的其他项目可能会产生解析错误。到 避免这个问题,使用合格的tbl_name.* 参考

SELECT AVG(score), t1.* FROM t1 ...

文档似乎表明 * 本身仅在选择列表中唯一的特殊情况下才有效。但是,它只是说将不合格的* 与其他项目一起使用可能会产生解析错误。

除了 MySQL,SQL-92 standard(旧的,但可链接的)也说了很多:

7.9  <query specification>

         Format

         <query specification> ::=
              SELECT [ <set quantifier> ] <select list> <table expression>

         <select list> ::=
                <asterisk>
              | <select sublist> [  <comma> <select sublist> ... ]

         <select sublist> ::=
                <derived column>
              | <qualifier> <period> <asterisk>

         <derived column> ::= <value expression> [ <as clause> ]

         <as clause> ::= [ AS ] <column name>

&lt;select list&gt; 可以是 &lt;asterisk&gt; 本身“普通”选择列表。

【讨论】:

select *, count(*) ... 成功。【参考方案2】:

但是

select *, f from blegg 

会正常工作。

可能不合格的 * 必须作为 select 中的第一个表达式出现?

【讨论】:

【参考方案3】:

可能是因为您选择了两次相同的字段。在以下查询中

select name, * from <...>

* 将包含name,因此您第二次明确指定name

这不是一个令人信服的论点,因为以下是有效的:

select name, name from <...>

下面也是这样

select name, users.* from users

两者都会多次选择同一个字段。

更有可能只是 MySQL 的语法限制。

【讨论】:

不,不是这样:select count(*), * from blegg 也失败了 但是,他的第一个工作示例做了同样的事情(并且在输出中包含两次 f)。 这不是一个很好的答案,但是对于评论来说太长/太复杂了。如果/当有人提供更具体的解释时,会很乐意删除。

以上是关于为啥在 MySQL 查询中添加 '*' 会导致语法错误?的主要内容,如果未能解决你的问题,请参考以下文章

为啥向这个 MySQL 查询添加特定的 where 子句会成为性能瓶颈?

mysql只能取出一条记录为啥不显示

为啥 MySQL DELETE 无法对子查询使用索引?

Access 2013:为啥会出现此语法错误?

为啥解包元组会导致语法错误?

如何解决我的查询中缺少数组项导致的 MySQL 语法错误?