我有一张表格,其中多个帐号与不同的ID(DR_NAME)相关联。每个帐户可能只有0个帐户,多达16个帐户。我相信UNPIVOT会起作用,但我使用的是Oracle 10g,它不支持这个。
DR_NAME ACCT1 ACCT2 ACCT3 ACC4
======================================
SMITH 1234
JONES 5678 2541 2547
MARK NULL
WARD 8754 6547
我想为每个名称显示一个新行,每行只有一个帐号
DR_NAME ACCT
==============
SMITH 1234
JONES 5678
JONES 2541
JONES 2547
MARK NULL
WARD 8754
WARD 6547
答案 0 :(得分:1)
Oracle 10g没有UNPIVOT
函数,但您可以使用UNION ALL
查询将列拆分为行:
select t1.DR_NAME, d.Acct
from yourtable t1
left join
(
select DR_NAME, ACCT1 as Acct
from yourtable
where acct1 is not null
union all
select DR_NAME, ACCT2 as Acct
from yourtable
where acct2 is not null
union all
select DR_NAME, ACCT3 as Acct
from yourtable
where acct3 is not null
union all
select DR_NAME, ACCT4 as Acct
from yourtable
where acct4 is not null
) d
on t1.DR_NAME = d.DR_NAME;
此查询使用UNION ALL
将列转换为行。我添加了where
子句以删除任何null
值,否则您将为acct值为null的每个帐户获取多行。排除null
值会删除您在最终结果中显示的dr_name = Mark
。要包含只有null
值的行,我再次将连接添加到表中。
答案 1 :(得分:1)
我知道的最有效的方法是使用某种逻辑进行交叉连接:
select *
from (select t.dr_name,
(case when n.n = 1 then acct1
when n.n = 2 then acct2
when n.n = 3 then acct3
when n.n = 4 then acct4
end) as acct
from t cross join
(select 1 as n from dual union all
select 2 from dual union all
select 3 from dual union all
select 4 from dual
) n
) s
where acct is not null
union all
方法通常会为每个子查询扫描一次表。这种方法通常会扫描一次表。
答案 2 :(得分:1)
如果您只对插入这些记录感兴趣,那么请查看多表插入 - 对数据进行单次扫描并生成多行,这样效率非常高。
此处的代码示例:http://docs.oracle.com/cd/B28359_01/server.111/b28286/statements_9014.htm#SQLRF01604
请注意,您可以使用多行的语法多次引用同一个表。
insert all
when acct1 is not null then into target_table (..) values (dr_name,acct1)
when acct2 is not null then into target_table (..) values (dr_name,acct2)
when acct3 is not null then into target_table (..) values (dr_name,acct3)
when acct4 is not null then into target_table (..) values (dr_name,acct4)
select
dr_name,
acct1,
acct2,
acct3,
acct4
from my_table.