0

我有一个表,其中多个帐号与不同的 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
4

3 回答 3

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;

请参阅SQL Fiddle with Demo

此查询使用 aUNION ALL将列转换为行。我包含了一个where删除任何null值的子句,否则您将为每个帐户获得多行,其中 acct 值为空。排除null值将删除dr_name = Mark您在最终结果中显示的值。为了包含只有null值的行,我再次将联接添加到表中。

于 2013-05-02T14:08:11.037 回答
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方法的典型结果是为每个子查询扫描一次表。这种方法通常会扫描表一次。

于 2013-05-02T14:13:27.180 回答
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.
于 2013-05-02T18:00:35.837 回答