我发现在这两个数据库之间如何解释查询有不同的行为,并想知道是否有人可以对这里发生的事情有所了解。查询如下所示:
SELECT t1.id, t2.album_id
FROM t1
LEFT OUTER JOIN t2
ON t1.data_id = t2.id
AND t1.event_type IN (1002, 1001, 1000)
WHERE
t1.event_type IN (1000, 1001, 1002, 1200, 1201, 1202, 1203)
GROUP BY t1.id
ORDER BY t1.id DESC
LIMIT 0, 20;
MariaDB结果如下所示:
+-----+----------+
| id | album_id |
+-----+----------+
| 623 | NULL |
| 622 | NULL |
| 621 | NULL |
| 620 | NULL |
| 619 | NULL |
| 618 | NULL |
| 617 | NULL |
| 616 | NULL |
| 615 | NULL |
| 614 | NULL |
| 613 | NULL |
| 612 | 194 |
| 611 | NULL |
| 610 | NULL |
| 609 | NULL |
| 608 | 193 |
| 607 | NULL |
| 606 | NULL |
| 605 | NULL |
| 604 | NULL |
+-----+----------+
Oracle MySQL结果如下所示:
+-----+----------+
| id | album_id |
+-----+----------+
| 623 | NULL |
| 622 | NULL |
| 621 | NULL |
| 620 | NULL |
| 619 | NULL |
| 618 | NULL |
| 617 | NULL |
| 616 | 196 |<-- different
| 615 | NULL |
| 614 | NULL |
| 613 | NULL |
| 612 | 194 |
| 611 | 194 |<-- different
| 610 | NULL |
| 609 | NULL |
| 608 | 193 |
| 607 | 193 |<-- different
| 606 | NULL |
| 605 | NULL |
| 604 | NULL |
+-----+----------+
此外,当我解析查询时,我可以看到两个数据库以不同方式解释查询。 (参见&#34;额外&#34;栏目)
MariaDB的
+------+-------------+-------+--------+---------------+---------+---------+------------------------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------+--------+---------------+---------+---------+------------------------+------+-------------+
| 1 | SIMPLE | t1 | index | NULL | PRIMARY | 4 | NULL | 20 | Using where |
| 1 | SIMPLE | t2 | eq_ref | PRIMARY | PRIMARY | 4 | foo.t1.data_id | 1 | Using where |
+------+-------------+-------+--------+---------------+---------+---------+------------------------+------+-------------+
Oracle MySQL
+----+-------------+-------+--------+---------------+---------+---------+---------------------------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+--------+---------------+---------+---------+---------------------------+------+-------------+
| 1 | SIMPLE | t1 | index | NULL | PRIMARY | 4 | NULL | 20 | Using where |
| 1 | SIMPLE | t2 | eq_ref | PRIMARY | PRIMARY | 4 | foo.t1.data_id | 1 | |
+----+-------------+-------+--------+---------------+---------+---------+---------------------------+------+-------------+
我找到了相关的解决方法,但我真的很想知道这里发生了什么。有没有人有任何想法?
如果您想自己尝试一下,可以找到我在本例中使用的数据转储here。
感谢。
编辑:在评论中已经指出,查询在大多数数据库中都是无效的SQL,但是MySQL allows - 但数据库可以自由地从GROUP BY返回任何聚合值。我只是想指出,这里似乎发生的事情是不同的,因为价值观并不模糊。只有一个匹配的行,但这与MariaDB返回的值不对应。
SELECT t1.id, t2.album_id
FROM t1
JOIN t2
ON t1.data_id = t2.id
WHERE
t1.id = 616
;
+-----+----------+
| id | album_id |
+-----+----------+
| 616 | 196 |
+-----+----------+
1 row in set (0.00 sec)
答案 0 :(得分:2)
事实证明,这实际上是MariaDB中的bug,当在2个条件下使用group by和left join时会产生错误的结果。
答案 1 :(得分:1)
此查询使用了对GROUP BY 的强烈 MySql扩展名
有关详细信息,请参阅此链接:http://dev.mysql.com/doc/refman/5.7/en/group-by-extensions.html
他们明确表示:
MySQL扩展了GROUP BY的使用,以便选择列表可以引用 未在GROUP BY子句中命名的非聚合列。这意味着 前面的查询在MySQL中是合法的。您可以使用此功能 通过避免不必要的列排序来获得更好的性能 分组。但是,这主要适用于每个中的所有值 GROUP BY中未命名的非聚合列对于每个列都是相同的 组。 服务器可以自由选择每个组中的任何值,所以 除非它们相同,否则所选择的值是不确定的。
考虑到上述情况,此行为符合规范。