MySQL 8在选择不同的查询中不检测功能依赖性

问题描述 投票:0回答:2

我使用此查询创建一个表:

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):ORDER BY子句的表达式#1不在SELECT列表中,引用列'portal.a.b'不在SELECT列表中;这与DISTINCT不兼容

但是,如果我将查询更改为

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

它在逻辑上是等价的,它成功了。

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

mysql Ver 8.0.12 for x86_64上的Linux(MySQL社区服务器 - GPL)

似乎MySQL仍然没有在选择不同的查询中检测功能依赖性。我对吗? MySQL的开发人员是否会解决这个问题?

mysql select distinct functional-dependencies
2个回答
0
投票

相反的行为实际上报告为一个bug和fixed in MySQL 5.7.5

与ONLY_FULL_GROUP_BY SQL模式相关的几个问题已得到纠正:

  • 启用ONLY_FULL_GROUP_BY后,如果访问的表被视图替换,则会拒绝某些有效查询。
  • SELECT DISTINCT col1 ... ORDER BY col2形式的查询符合SQL2003禁用(隐藏的ORDER BY列与DISTINCT结合),但在启用ONLY_FULL_GROUP_BY SQL模式时未被拒绝。

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

若要防止此问题,如果任何ORDER BY表达式不满足以下条件中的至少一个,则具有DISTINCT和ORDER BY的查询将被拒绝为无效:

  • 表达式在选择列表中等于1
  • 表达式引用并属于查询所选表的所有列都是选择列表的元素

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

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


0
投票

这来自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上看到它

© www.soinside.com 2019 - 2024. All rights reserved.