mysql 5.7.5+get组的第一行

l2osamch  于 2021-06-20  发布在  Mysql
关注(0)|答案(1)|浏览(309)

我有一个遗留应用程序 Group By 已与非聚合列一起用于获取每个组的第一行。查询如下:

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_FULL_GROUP_BY 模式。
是的,我可以按照以下方式重写查询,以便根据新的行为工作:

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。
fiddle 5.7禁用了“only\u full\u group by”和意外结果:
https://www.db-fiddle.com/f/8vjb7xpkobwvyxppvuagt2/0
摆弄5.6默认模式和预期结果:
https://www.db-fiddle.com/f/8vjb7xpkobwvyxppvuagt2/1
我的问题是:有没有办法禁用这种随机选择的行为,这样遗留代码就可以在不重写它们或降级的情况下工作?
非常感谢您的建议!

gmol1639

gmol16391#

你的 ORDER BY 在mysql 5.7中,派生表中的子查询被忽略。
看到了吗https://dev.mysql.com/doc/refman/5.7/en/derived-table-optimization.html
如果以下条件均为真,则优化器会将派生表或视图引用中的order by子句传播到外部查询块:
外部查询未分组或聚合。
外部查询没有指定distinct、having或order by。
外部查询将此派生表或视图引用作为from子句中的唯一源。
否则,优化器将忽略ORDERBY子句。
您的外部查询有一个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 |
+------------------+----------------+---------+---------+

相关问题