MySQL 5.7.5+;获取组的第一行

MySQL 5.7.5+;获取组的第一行,mysql,mysql-5.7,Mysql,Mysql 5.7,我有一个遗留应用程序,其中使用了groupby和非聚合列来获取每个组的第一行。查询如下: SELECT columnPrimaryKey, column1, column2, column3 FROM (SELECT columnPrimaryKey, column1, column2, column3 FROM testTable ORDER BY column2 ) AS

我有一个遗留应用程序,其中使用了
groupby
和非聚合列来获取每个组的第一行。查询如下:

SELECT
    columnPrimaryKey,
    column1,
    column2,
    column3
FROM
    (SELECT
        columnPrimaryKey,
        column1,
        column2,
        column3
    FROM testTable
    ORDER BY column2
) AS tbl
GROUP BY column3
最近,该版本更新为5.7.22,现在,即使通过模式禁用了
ONLY\u FULL\u GROUP\u,上述查询也不会返回预期结果

是的,我可以按照以下方式重写查询,以便根据新的行为工作:

SELECT
    x.columnPrimaryKey,
    x.column1,
    x.column2,
    x.column3
FROM tableName AS x INNER JOIN (
    SELECT
        MIN( column2 ) AS column2,
        column3
    FROM tableName
    GROUP BY column3
) AS y ON x.column2 = y.column2 AND x.column3 = y.column3;
不幸的是,现在这不是一个选择。我看到的唯一选择是提前降级到5.7.5

在5.7版中禁用了“仅满组”和意外结果:

用默认模式和预期结果摆弄5.6:

我的问题是:有没有办法禁用这种随机选择行为,以便遗留代码在不重写或降级的情况下工作


非常感谢您的任何建议

在MySQL 5.7中,派生表子查询中的
ORDER BY
被忽略

优化器在派生表或视图中传播ORDERBY子句 如果这些条件均为真,则引用外部查询块:

  • 外部查询未分组或聚合

  • 外部查询未指定DISTINCT、HAVING或ORDER BY

  • 外部查询将此派生表或视图引用作为FROM子句中的唯一源

否则,优化器将忽略ORDERBY子句

外部查询有一个联接和一个分组依据,因此它不符合传播ORDER BY的条件,因此它忽略ORDER BY

此优化器行为由优化器开关
derived\u merge
控制。你可以禁用它

演示:


我不知道你的问题有什么解决办法。经验教训:不要只依赖于关闭完整的分组模式。如您所见,无法保证结果是确定性的,此外,如果您必须对其进行移植,您的查询甚至不会在大多数其他数据库上运行。@TimBiegeleisen您完全正确,但正如我所说,这是一个遗留应用程序,因此我现在希望避免重写查询。这让我只剩下一个解决方案,即,降级版本:(然后降级一段时间,当你有机会重写查询时,再次升级。IMO没有问题。@TimBiegeleisen是的,必须这样做。感谢这是在较新的MySQL和MariaDB()中发生的(p.s MySQL文档没有这个文档)…在MySQL 5.7 fiddle“修复程序”中添加限制你的结果..好的,它被记录了,我评论说它没有记录在MySQL文档中..使用
设置优化器开关='derived\u merge=off'
查询在应用程序中连接到MySQL数据库后,应该保存topicstarter以重写所有查询..还可以全局设置优化器开关,并在/etc/my.cnf
mysql [localhost] {msandbox} (test) > select @@version;
+-----------+
| @@version |
+-----------+
| 5.7.21    |
+-----------+

mysql [localhost] {msandbox} (test) > SELECT     columnPrimaryKey,     column1,     column2,     column3 FROM     (SELECT         columnPrimaryKey,         column1,         column2,         column3     FROM testTable     ORDER BY column2 ) AS tbl GROUP BY column3;
+------------------+----------------+---------+---------+
| columnPrimaryKey | column1        | column2 | column3 |
+------------------+----------------+---------+---------+
|                1 | Some Name 8-4  |       4 |       8 |
|                6 | Some Name 9-1  |       1 |       9 |
|                8 | Some Name 10-2 |       2 |      10 |
+------------------+----------------+---------+---------+

mysql [localhost] {msandbox} (test) > set optimizer_switch = 'derived_merge=off';
Query OK, 0 rows affected (0.00 sec)

mysql [localhost] {msandbox} (test) > SELECT     columnPrimaryKey,     column1,     column2,     column3 FROM     (SELECT         columnPrimaryKey,         column1,         column2,         column3     FROM testTable     ORDER BY column2 ) AS tbl GROUP BY column3;
+------------------+----------------+---------+---------+
| columnPrimaryKey | column1        | column2 | column3 |
+------------------+----------------+---------+---------+
|                5 | Some Name 8-1  |       1 |       8 |
|                6 | Some Name 9-1  |       1 |       9 |
|                8 | Some Name 10-2 |       2 |      10 |
+------------------+----------------+---------+---------+