具有分析功能的oracle转置

时间:2018-01-09 07:12:33

标签: sql oracle pivot window-functions

我正在从表中转换键值对并面临问题。 我正在使用Oracle 12C database。 测试数据看起来像这样。表格为tab1

 +---------------------------+
 | Name | VAL  |  ID | grp_id|
 +---------------------------+
 |   a  |   3  |  1  | 1     |
 |   b  |   5  |  2  | 1     |
 |   c  |   8  |  3  | 1     |
 |   c  |   9  |  4  | 2     |
 +---------------------------+ 

我的预期结果是

 +-------------------------+
 | grp_id|   a  |   b  | c |
 +-------------------------+
 |   1   |   3  |   5  | 8 | 
 |   2   | null | null | 9 |  
 +-------------------------+

到目前为止我做的是

with t as(
select row_number() over (partition by grp_id order by grp_id) rn,
name,
grp_id,
lead(val,0) over (partition by grp_id order by grp_id) as a,
lead(val,1) over (partition by grp_id order by grp_id) as b,
lead(val,2) over (partition by grp_id order by grp_id) as c
from tab1 where grp_id  in (1,2) and name in ('a', 'b','c')
)
select grp_id,a,b,c from t where rn=1;

当数据一致且所有grp_id - s键值对相同​​时,此查询工作正常,但是如果一个grp_id缺少某些键,那么我会得到一个结果以下是错误的而不是我的期望

 +----------------------------+
 | grp_id|   a  |   b  | c    |
 +----------------------------+
 |   1   |   3  |   5  | 8    | 
 |   2   |   9  | null | null |  
 +----------------------------+

如何改进查询以正常工作?我想避免使用pivot

1 个答案:

答案 0 :(得分:1)

我会使用条件聚合来做到这一点:

select grp_id,
       max(case when name = 'a' then val end) as a,
       max(case when name = 'b' then val end) as b,
       max(case when name = 'c' then val end) as c
from tab1
group by grp_id;

grp_id已经定义,因此我认为不需要分析函数。