将多行合并为一行?

时间:2013-01-15 11:05:33

标签: sql oracle plsql oracle11g plsqldeveloper

我有一个阶段表'STAGE_TABLE',其中包含以下值(列是varchar2除了ids) -

+-------------------------------------------------------------------------------------------------------------------------
¦  STAGE_ID ¦ EMP_ID     ¦ ATTR1_OLD_VAL ¦ ATTR1_NEW_VAL ¦ ATTR2_OLD_VAL ¦ ATTR2_NEW_VAL ¦ ATTR3_OLD_VAL ¦ ATTR3_NEW_VAL ¦
¦-----------+------------+---------------+---------------+---------------+---------------+---------------+---------------¦
¦         1 ¦       E001 ¦ xyz           ¦ pqr           ¦ mmm           ¦ nnn           ¦ zzz           ¦ aaa           ¦
¦         2 ¦       E001 ¦               ¦               ¦               ¦               ¦               ¦               ¦
¦         3 ¦       E001 ¦ pqr           ¦ abc           ¦ xxx           ¦ yyy           ¦               ¦               ¦
¦         4 ¦       E002 ¦ aaa           ¦ ccc           ¦ bbb           ¦ ttt           ¦               ¦               ¦
¦         5 ¦       E002 ¦               ¦               ¦               ¦               ¦ fff           ¦ ppp           ¦
¦         6 ¦       E002 ¦               ¦               ¦ kkk           ¦ jjj           ¦               ¦               ¦
+-------------------------------------------------------------------------------------------------------------------------

我想将属于同一员工的上表中的多行合并为一个 -

+-------------------------------------------------------------------------------------------------------------
¦ EMP_ID     ¦ ATTR1_OLD_VAL ¦ ATTR1_NEW_VAL ¦ ATTR2_OLD_VAL ¦ ATTR2_NEW_VAL ¦ ATTR3_OLD_VAL ¦ ATTR3_NEW_VAL ¦
¦------------+---------------+---------------+---------------+---------------+---------------+---------------¦
¦       E001 ¦ pqr           ¦ abc           ¦ xxx           ¦ yyy           ¦ zzz           ¦ aaa           ¦
¦       E002 ¦ aaa           ¦ ccc           ¦ kkk           ¦ jjj           ¦ fff           ¦ ppp           ¦
+-------------------------------------------------------------------------------------------------------------

我开始了解MERGE声明,但不确定它是否有效。 我是oracle pl / sql的新手。

2 个答案:

答案 0 :(得分:3)

CREATE TABLE tmp 
  ( 
     row_id NUMBER, 
     id     NUMBER, 
     t1     VARCHAR2(5), 
     t2     VARCHAR2(5), 
     t3     VARCHAR2(5) 
  ); 

INSERT INTO tmp 
VALUES      (1, 
             1, 
             'a', 
             NULL, 
             'a'); 

INSERT INTO tmp 
VALUES      (2, 
             1, 
             NULL, 
             'b', 
             'b'); 

INSERT INTO tmp 
VALUES      (3, 
             1, 
             'c', 
             NULL, 
             NULL); 

INSERT INTO tmp 
VALUES      (1, 
             2, 
             'a', 
             'a', 
             NULL); 

INSERT INTO tmp 
VALUES      (2, 
             2, 
             NULL, 
             'b', 
             NULL); 

所以,我们应该得到:1,C,B,B和2,A,B,NULL:

select id_merged, T1,T2,T3 from 
( SELECT id id_merged,
 first_value(T1 IGNORE nulls) over (partition BY id ORDER BY row_id DESC) T1,
 first_value(T2 IGNORE nulls) over (partition BY id ORDER BY row_id DESC) T2,
 first_value(T3 IGNORE nulls) over (partition BY id ORDER BY row_id DESC) T3,
 rank () over (partition by id order by row_id) rn
FROM tmp)
where rn=1 ORDER BY id_merged;

答案 1 :(得分:0)

您可以使用group by emp_id并使用keep dense_rank选择属性值:

select 
  emp_id,
  max(ATTR1_OLD_VAL) keep (dense_rank first order by decode(ATTR1_OLD_VAL,null,1,0), stage_id desc) as ATTR1_OLD_VAL
from STAGE_TABLE
group by emp_id;

order by decode(ATTR1_OLD_VAL,null,1,0)将空值放到最后。从具有非空值的那些中选择最新的stage_id desc

我放了一个属性你应该把其他属性。