OB SQL分组后取每组第一条数据

OB MySQL模式的关闭ONLY_FULL_GROUP_BY时,与mysql存在兼容性问题。
场景:对数据进行分组,每组排序,并取第一条数据。
表结构:

CREATE TABLE `t1` (
  `a` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'a',
  `b` varchar(120) NOT NULL COMMENT 'b',
  PRIMARY KEY (`a`)
) ENGINE=InnoDB AUTO_INCREMENT=122289 DEFAULT CHARSET=utf8mb4 COMMENT='测试表t1';
CREATE TABLE `t2` (
  `c` int(11) NOT NULL AUTO_INCREMENT COMMENT 'c',
  `d` varchar(120) NOT NULL COMMENT 'd',
  `e` date NOT NULL COMMENT 'e',
  `f` int(11) NOT NULL COMMENT 'f',
  PRIMARY KEY (`c`),
  KEY `idx_d` (`d`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=539037 DEFAULT CHARSET=utf8mb4 COMMENT='t2';

测试SQL如下:

SELECT
	* 
FROM
	(
	SELECT
        distinct 
		t1.b as b,
		t2.c as c,
		t2.d as d,
		t2.e as e,
        t2.f as f
	FROM
		t1
		INNER JOIN t2 ON t1.b = t2.d
        where b='2y'
	ORDER BY
		t2.e desc 
	) tmp 
GROUP BY
	b;

MySQL结果:

image
OB结果:

image
tmp表排序是这样的:
image

MySQL可以正常取出,OB取出来除了b列,其他的不是每组排序的第一条数据。从MySQL迁移时需要进行大量的排查和改造。请问有什么好的解决办法吗?比如配置,hint等。附件为测试表结构及数据,可直接导入测试。
303_export_file.zip (6.9 MB)

2 个赞

你把你查询的结果 截图看一下?另外你把表结构发一下 这边测试一下 还有你用的ob的版本和mysql的版本也发一下

2 个赞

谢谢。题目中已补充,版本OB是4.3.1,mysql是5.7.43。

2 个赞

好的 我们测试一下 稍后回复你

2 个赞

执行计划里order by直接被改写掉了。


这里与MySQL的改写不同。
MySQL :: MySQL 5.7 Reference Manual :: 8.2.2.4 Optimizing Derived Tables and View References with Merging or Materialization
加distinct后,不会忽略order by.

2 个赞

按照ob的语法来说 是没有问题的 按照需要按里层排序,实际上不会的,sql没这么规定,如果要最终结果有保证,他外层要写好order by 即使拿计划看 里层的order by也是被消除了

2 个赞

外层写好order by语义不一样了,如果不改SQL的话,这里目前看来只能禁用改写处理。

2 个赞

你可以尝试改写 因为排序其实在传递到外层的时候 外层其实是不确定的

2 个赞

OK,3Q

2 个赞

如果帖子的问题 已经解决 请点一下采纳 谢谢