oracle 多行 转 一行

aa

在项目中出现了一个需求,根据一个参数,查询到两张单子,每张单子里存有很多人的信息,两张单子中可能有相同的人。现在要将两张单子中的同一个人合并。简化如下:

假设有表T,里面有这样的数据 :

orderNo          name        height     gender      grade
4               ZhaoWei      168         女          专家
3               ZhaoWei      168         女          观众
2            HuangXiaoMing   175         男          观众
1               HuGe         188         男          专家

可以看出ZhaoWei的记录数据有重复,希望可以合并。现在要有如下的效果:

orderNo          name        height     gender      grade      aff
4               ZhaoWei      168         女          专家     专家,观众
2            HuangXiaoMing   175         男          观众       观众 
1               HuGe         188         男          专家       专家

 第一步:根据姓名分类,生成合并的列aff. (为什么分步,搞得稍稍繁杂,是因为需要应付查询很多列的情况。不可能group by 后接很多的列名。 )

SELECT t.name,wm_concat(t.grade) aff
FROM t
group by t.name

第二步:给T表中的相同姓名的人编码,以等待后续删除一条的操作

    SELECT row_number() over(partition by t.name order by t.orderNo) RK,
           t.orderNo,
           t.name,
           t.height,
           t.gender,
           t.grade
    FROM T
    

第三步:合并

WITH temp AS(select t.name,wm_concat(t.grade) AFF from t group by t.name),

SELECT temp.AFF,tab.* 
FROM
      (SELECT row_number() over(partition by t.name order by t.orderNo) RK,
           t.orderNo,
           t.name,
           t.height,
           t.gender,
           t.grade
        FROM T)tab,
        temp
 WHERE temp.name=tab.name
 AND tab.RK=1

一些入参没给出,稍稍简化了。

这里有三个点,一个是with as 的用法,

其二是 wm_concat函数,

其三是 row_number排序。

row_number()是没有重复值 的排序,

dense_rank()是连续排序,

rank()是跳跃排序。

假如有四个人的成绩为 100,99,99,98。

row_number() 会是 1, 2, 3, 4 

dense_rank() 会是 1, 2, 2, 3 

rank() 则是1, 2, 2 ,4 

猜你喜欢

转载自blog.csdn.net/sethwiseman/article/details/84647139