MySQL 5.7.5+获得组的第一行

时间:2018-08-22 14:29:36

标签: mysql mysql-5.7

我有一个旧版应用程序,其中$('#player')[0].pause(); $('#player').one('loadeddata', mvidPros); $('#player')[0].load(); 与非聚合列一起使用以获取每个组的第一行。查询如下:

Group By

最近,该版本已更新为5.7.22,现在即使禁用了SELECT columnPrimaryKey, column1, column2, column3 FROM (SELECT columnPrimaryKey, column1, column2, column3 FROM testTable ORDER BY column2 ) AS tbl GROUP BY column3 模式,上述查询也没有返回预期的结果。

是的,我可以按照以下新行为将查询重写如下:

ONLY_FULL_GROUP_BY

不幸的是,这不是目前的选择。我看到的唯一选择是更早降级到5.7.5。

小提琴5.7禁用了“仅ONLY_FULL_GROUP_BY”并出现了意外结果:

https://www.db-fiddle.com/f/8VjB7XpkobWVyXpPvUaGt2/0

提琴5.6带有默认模式和预期结果:

https://www.db-fiddle.com/f/8VjB7XpkobWVyXpPvUaGt2/1

我的问题是:是否有任何方法可以禁用这种随机选择行为,以使旧代码无需重写或降级即可工作?

任何建议,不胜感激!

1 个答案:

答案 0 :(得分:0)

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

请参见https://dev.mysql.com/doc/refman/5.7/en/derived-table-optimization.html

  

优化器在派生表或视图中传播ORDER BY子句   如果这些条件都成立,则引用外部查询块:

     
      
  • 外部查询未分组或聚合。

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

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

  •   
     

否则,优化器将忽略ORDER BY子句。

您的外部查询具有JOIN和GROUP BY,因此它没有资格传播ORDER BY,因此它会忽略ORDER BY。

此优化器行为由优化器开关derived_merge控制。您可以禁用它。

演示:

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 |
+------------------+----------------+---------+---------+