情景
假设有表 user_log
,要求按照 user_id 字段分组,然后对应的 remark 用 ,
隔开。
user_id remark
1 124
1 222
2 124
2 134
Group By 实现方式
wm_contact
直接按照逗号分隔 remark 结果。
SELECT wm_concat(remark), user_id FROM user_log
GROUP BY user_id;
- 使用报错
oracle wmsys.wm_concat ORA-00932: 数据类型不一致: 应为 -, 但却获得 CLOB
oracle 函数 wmsys.wm_concat 在 10.2.0.4版本以前是 varchar2 类型,但是 从 10.2.0.5 开始,是 CLOB 类型,是一个坑!!
改成 to_char(wm_concat( ...... ))
解决
LISTAGG
当然需求是多变的,还有可能按照其他符号分隔。
使用 LISTAGG(remark,’,’)
第二个参数可以指定连接符号。
SELECT user_id, (LISTAGG(remark,',') WITHIN group(order by remark)) AS remark
FROM user_log
GROUP BY user_id;
给予内存分组
还有一种方式。首先查询出所有结果,然后基于内存进行分组。
可以参考:基于 guava 的内存分组
删除重复配置
场景描述
有时候我们需要移除重复的配置,并且删除掉重复的配置,并且只保留一个需要的配置。
分析
需要根据判定是否重复的字段
group by XXX, XXX having count(0) > 1;
示例 sql
DELETE MY_CONFIG t
where exists (
select * from (
select max(rowid) rowid_, xxx,count(0) cnt
from MY_CONFIG group by xxx
) b where cnt >1 and t.rowid = b.rowid_
);
这里就是把分组后得到 cnt > 1(有重复的配置)选取出第一条,然后进行删除。