MySQL 8 不检测 select 不同查询中的函数依赖

MySQL 8 does not detect functional dependencies in select distinct queries

我使用此查询创建了一个 table:

create table a (
  `id` int not null auto_increment,
  b varchar(10),
  primary key (`id`)
);

正在执行

select distinct `id` from a order by `b`;

导致此错误:

ERROR 3065 (HY000): Expression #1 of ORDER BY clause is not in SELECT list, references column 'portal.a.b' which is not in SELECT list; this is incompatible with DISTINCT

但是如果我将查询更改为

select `id` from a group by `id` order by `b`;

逻辑上等价,成功

我正在使用 official Docker image for MySQLmysql --version 显示器

mysql Ver 8.0.12 for Linux on x86_64 (MySQL Community Server - GPL)

似乎 MySQL 仍未检测到 select 不同查询中的功能依赖性。我对吗? MySQL 的开发人员会解决这个问题吗?

这来自 MySQL 5.7 引入的新 SQL 模式:ONLY_FULL_GROUP_BY

此模式的目标是使 MySQL 在 GROUP BY 查询中表现得像 SQL 标准。

此模式已在您的数据库上激活。您可以禁用它,或调整您的查询以遵守标准,这可能是最好的做法。

这将引发您的错误:

SET sql_mode = 'ONLY_FULL_GROUP_BY';

drop table a;
create table a (
  `id` int not null auto_increment,
  b varchar(10),
  primary key (`id`)
);
INSERT INTO a VALUES (NULL, 'aaaa');
INSERT INTO a VALUES (NULL, 'bbbb');

select distinct `id` from a order by `b`;

如果删除 ONLY_FULL_GROUP_BY 模式,您将得到结果:

SET sql_mode = '';

drop table a;
create table a (
  `id` int not null auto_increment,
  b varchar(10),
  primary key (`id`)
);
INSERT INTO a VALUES (NULL, 'aaaa');
INSERT INTO a VALUES (NULL, 'bbbb');

select distinct `id` from a order by `b`;

你可以在 Rextester

上看到直播

相反的行为实际上被报告为错误并且fixed in MySQL 5.7.5:

Several issues related to the ONLY_FULL_GROUP_BY SQL mode were corrected:

  • With ONLY_FULL_GROUP_BY enabled, some valid queries were rejected if the accessed table was replaced by a view.

  • Queries of the form SELECT DISTINCT col1 ... ORDER BY col2 qualify as forbidden by SQL2003 (hidden ORDER BY columns combined with DISTINCT), but were not rejected with the ONLY_FULL_GROUP_BY SQL mode enabled.

此外,documentation 明确指出这是预期的行为:

To prevent this problem, a query that has DISTINCT and ORDER BY is rejected as invalid if any ORDER BY expression does not satisfy at least one of these conditions:

  • The expression is equal to one in the select list

  • All columns referenced by the expression and belonging to the query's selected tables are elements of the select list

没有提到函数依赖。与group by相反,相关错误消息也没有引用功能依赖项。

虽然 sql 标准中的可选特性 T301 功能依赖性 确实 修改了 [=10= 的一致性规则](和其他人),它不会改变对 order by 加上 distinct 的任何限制,这意味着它仍然是禁止的。