使用string_agg函数查询执行结果不稳定
问题现象
SQL语句查询结果不一致。
原因分析
某业务场景中的SQL语句中使用了string_agg函数,语句逻辑如下:
执行如下SQL语句:
1 2 3 4 |
select count(*) from (select deptno, string_agg(ename, ',') from employee group by deptno) t1 , (select deptno, string_agg(ename, ',') from employee group by deptno) t2 where t1.string_agg = t2.string_agg; |
在循环多次执行这个语句的时候,发现结果不稳定,输出结果有时候是t1,有时候是t2,因此怀疑是数据库有问题,结果集不正确。
String_agg函数的作用是将组内的数据合并成一行,但是如果用户用法是string_agg(ename, ',')这种情况下,结果集就是不稳定的,因为没有指定组合的顺序。
例如,上述SQL语句中的输出结果可以是以下任意一种,且都是合理的。
30 | ALLEN,MARTIN 30 | MARTIN,ALLEN
因此有可能出现t1这个subquery中的结果和t2这个subquery中的结果对于deptno=30的时候的输出结果是不一样的。
处理方法
String_agg中增加order by,语句修改为如下格式保证ename字段是按照相同的顺序来拼接的,从而满足查询结果是稳定的。
1 2 3 4 |
select count(*) from (select deptno, string_agg(ename, ',' order by ename desc) from employee group by deptno) t1 , (select deptno, string_agg(ename, ',' order by ename desc) from employee group by deptno) t2 where t1.string_agg = t2.string_agg; |