2013-05-02 40 views
0

我有一張表,其中多個帳號與不同的ID(DR_NAME)相關聯。每個帳戶最多隻能有0個帳戶,多達16個。我相信UNPIVOT可以工作,但我使用的是Oracle 10g,但不支持此功能。如何在Oracle 10g中將多個列值作爲新行返回?

DR_NAME ACCT1 ACCT2 ACCT3 ACC4 
====================================== 
SMITH  1234 
JONES  5678 2541 2547 
MARK  NULL  
WARD  8754 6547 

我想顯示每個名稱的新行,每行只有1個賬號

DR_NAME ACCT 
============== 
SMITH  1234 
JONES  5678 
JONES  2541 
JONES  2547 
MARK  NULL 
WARD  8754 
WARD  6547 
+0

多少數據行做你需要做的這因爲在單個查詢中,您是否需要選擇該數據或將其插入到表中? – 2013-05-02 14:09:09

+0

@DavidAldridge大約1500行的初始數據,據我估計,當每個DR_NAME僅與1個ACCT配對時,可能會產生大約6000行。它需要被插入到一個表中 – user2249376 2013-05-02 14:26:28

回答

1

Oracle 10g中不具有UNPIVOT功能,但你可以使用一個UNION ALL查詢UNPIVOT列成行:

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

此查詢使用UNION ALL將列轉換爲行。我包含一個where子句以刪除任何null值,否則您將針對acct值爲空的每個帳戶獲取多行。不包含null值將會減少您在最終結果中顯示的dr_name = Mark。要包含只有null值的行,我再次將該連接添加到表中。

+0

你想添加謂詞以避免返回空值 – 2013-05-02 14:09:39

+0

@DavidAldridge你是對的,我稍微修改了它,因爲它們實際上是想返回所有'DR_NAME'值。如果我排除'null',那麼他們將不會得到'Mark' – Taryn 2013-05-02 14:14:31

+0

@ user2249376我不確定你的意思?我根據您的示例顯示了每個dr_name的多行 - http://www.sqlfiddle.com/#!4/b8801/10 - Jones有3行,Mark = 1,Smith = 1和Ward = 2 – Taryn 2013-05-02 14:47:06

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方法的典型結果。這種方法通常會掃描一次表格。

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. 
+0

謝謝。我會試試這個。我有一個目前可行的解決方案,但這可能會更有效率。 – user2249376 2013-05-02 19:54:24