我多次被告知,相同的查询MariaDB的工作原理与MySQL上的相同,直到遇到此问题。MariaDB的“GROUP BY”与MySQL的行为不同
最近,我试图从MySQL的(InnoDB的)克隆应用程序MariaDB的(XtraDB)。 尽管MariaDB无需更改任何内容即可运行MySQL查询,但我惊讶地发现相同的查询在两种平台上的表现实际上都有所不同,特别是在ORDER BY和GROUP BY。
举一个例子:
MyTable
=======
+----+----------+---------------------+-----------+
| id | parentId | creationDate | name |
+----+----------+---------------------+-----------+
| 1 | 2357 | 2017-01-01 06:03:40 | Anna |
+----+----------+---------------------+-----------+
| 2 | 5480 | 2017-01-02 07:13:20 | Becky |
+----+----------+---------------------+-----------+
| 3 | 2357 | 2017-01-03 08:20:12 | Christina |
+----+----------+---------------------+-----------+
| 4 | 2357 | 2017-01-03 08:20:15 | Dorothy |
+----+----------+---------------------+-----------+
| 5 | 5480 | 2017-01-04 09:25:45 | Emma |
+----+----------+---------------------+-----------+
| 6 | 1168 | 2017-01-05 10:30:10 | Fiona |
+----+----------+---------------------+-----------+
| 7 | 5480 | 2017-01-05 10:33:23 | Gigi |
+----+----------+---------------------+-----------+
| 8 | 1168 | 2017-01-06 12:46:34 | Heidi |
+----+----------+---------------------+-----------+
| 9 | 1168 | 2017-01-06 12:46:34 | Irene |
+----+----------+---------------------+-----------+
| 10 | 2357 | 2017-01-07 14:58:37 | Jane |
+----+----------+---------------------+-----------+
| 11 | 2357 | 2017-01-07 14:58:37 | Katy |
+----+----------+---------------------+-----------+
基本上我想从查询得到的是最新记录来自每个分组(即parentId
)。通过最新的,我的意思是MAX(creationDate
)和MAX(id
)
所以,上面的例子中,由于只有三个不同的parentId的值,我希望能得到:
+----+----------+---------------------+-----------+
| id | parentId | creationDate | name |
+----+----------+---------------------+-----------+
| 11 | 2357 | 2017-01-07 14:58:37 | Katy |
+----+----------+---------------------+-----------+
| 9 | 1168 | 2017-01-06 12:46:34 | Irene |
+----+----------+---------------------+-----------+
| 7 | 5480 | 2017-01-05 10:33:23 | Gigi |
+----+----------+---------------------+-----------+
最初的应用有类似于这种方式查询:
SELECT * FROM
(SELECT * FROM `MyTable` WHERE `parentId` IN (...)
ORDER BY `creationDate` DESC, `id` DESC) AS `t`
GROUP BY `parentId`;
在MySQL的,这个工作,因为内部查询订货会,然后外部查询得到第一每组从RESU内部查询的内容。外部查询基本服从内部查询的排序。
但在MariaDB,外部查询将忽略内部查询结果的排序。我在MariaDB上得到这个:
+----+----------+---------------------+-----------+
| id | parentId | creationDate | name |
+----+----------+---------------------+-----------+
| 1 | 2357 | 2017-01-01 06:03:40 | Anna |
+----+----------+---------------------+-----------+
| 2 | 5480 | 2017-01-02 07:13:20 | Becky |
+----+----------+---------------------+-----------+
| 6 | 1168 | 2017-01-05 10:30:10 | Fiona |
+----+----------+---------------------+-----------+
为了在MariaDB上实现同样的行为,我想出了类似的东西。 (不知道这是正确的,但。)
SELECT `t1`.* FROM `MyTable` `t1` LEFT JOIN `MyTable` `t2` ON (
`t1`.`parentId` = `t2`.`parentId`
AND `t2`.`parentId` IN (...)
AND `t1`.`creationDate` <= `t2`.`creationDate`
AND `t1`.`id` < `t2`.`id`)
) WHERE `t2`.`id` IS NULL;
现在的问题是...如果我要重写查询,我要改写数百人......他们是一些如何一点点有点彼此不同。
我想知道这里有没有人有任何想法可以让我做出最小的改变。
谢谢大家提前。
MySQL手册涵盖了这一点。它提供了3种有效的解决方案。如果你还在挣扎,请参阅http://meta.stackoverflow.com/questions/333952/why-should-i-provide-an-mcve-for-what-seems-to-me-to-bea-a- very-simple-sql-query – Strawberry
检查你的mysql和mariaDB版本,并检查select中的列的方式必须由group by子句使用..你能否遇到与only_full_group_by设置模式不同的行为在你的db版本中有问题..你可以看到一些信息https://dev.mysql.com/doc/refman/5.7/en/sql-mode.html – scaisEdge
MySQL版本是5.5.52 ... MariaDB版本是10.1.21 ... 我有试图在MariaDB上运行SET sql_mode =“ONLY_FULL_GROUP_BY”,但没有任何区别。 – user2526586