在MySQL

时间:2016-01-09 07:49:44

标签: mysql

似乎在MySQL的5.7版中,他们为那些处理SQL Server的人添加了一个令人讨厌的东西(或者仍然是)真正的headache

问题是:当您尝试为一组列SELECT DISTINCT行并希望ORDER BY另一组列时,MySQL会抛出错误。以前,在5.6版本中甚至在5.7版本的某些版本中你可以这样做,但现在禁止它(至少在默认情况下是这样)。

我希望存在一些配置,我们可以设置一些变量来使其工作。但不幸的是,我不知道这个讨厌的变量。我希望有人知道。

修改

这是我案例中的一些典型查询,这些查询在字面上工作多年(直到MySQL 5.7的最后一次构建):

SELECT DISTINCT a.attr_one, a.attr_two, a.attr_three, b.attr_four FROM table_one a
LEFT JOIN table_two b ON b.some_idx = a.idx
ORDER BY b.id_order

事实上,如果我现在将b.id_order包含在SELECT部分(正如MySQL所建议的那样),那么我将得到的将是垃圾。

2 个答案:

答案 0 :(得分:9)

在大多数情况下,DISTINCT子句可以视为GROUP BY的特例。例如,

<强> ONLY_FULL_GROUP_BY

MySQL 5.7.5及更高版本实现了对功能依赖的检测。如果启用 ONLY_FULL_GROUP_BY SQL模式(默认情况下是这样),MySQL拒绝选择列表,HAVING条件或ORDER BY列表引用既未在GROUP BY中命名的非聚合列的查询条款也不在功能上依赖于它们。 (在5.7.5之前,MySQL不检测功能依赖性,默认情况下不启用ONLY_FULL_GROUP_BY。有关5.7.5之前行为的描述

如果禁用ONLY_FULL_GROUP_BY,则对GROUP BY的标准SQL使用的MySQL扩展允许选择列表,HAVING条件或ORDER BY列表引用非聚合列,即使这些列在功能上不依赖于GROUP BY列。这导致MySQL接受前面的查询。在这种情况下,服务器可以自由选择每个组中的任何值,因此除非它们相同,否则所选的值是不确定的,这可能不是您想要的。此外,添加ORDER BY子句不会影响每个组中值的选择。选择值后会发生结果集排序,ORDER BY不会影响服务器选择的每个组中的值。禁用ONLY_FULL_GROUP_BY主要是因为您知道由于数据的某些属性,每个未在GROUP BY中命名的非聚合列中的所有值对于每个组都是相同的。

了解更多http://dev.mysql.com/doc/refman/5.7/en/sql-mode.html#sqlmode_only_full_group_by

获取特定答案

SELECT DISTINCT attr_one,
            attr_two,
            attr_three,
            attr_four
FROM
  (SELECT a.attr_one,
      a.attr_two,
      a.attr_three,
      b.attr_four
   FROM table_one a
   LEFT JOIN table_two b ON b.some_idx = a.idx
   ORDER BY b.id_order) tmp

答案 1 :(得分:2)

我已经阅读了您提到的链接上的帖子,看起来已经清楚地解释了为什么会抛出错误以及如何避免错误。

在您的情况下,您可能需要尝试以下操作(当然未经过测试):

SELECT a.attr_one, a.attr_two, a.attr_three, b.attr_four 
FROM table_one a
LEFT JOIN table_two b ON b.some_idx = a.idx
GROUP BY a.attr_one, a.attr_two, a.attr_three, b.attr_four 
ORDER BY max(b.id_order)

您应该选择是使用ORDER BY max(b.id_order),还是ORDER BY min(b.id_order)或其他汇总功能