2016-03-03 67 views
1

我試圖找到合併2個表和透視的方法。需要注意的是,我使用的是oracle 9i版本,顯然沒有pivot功能。所以我希望我能解決這個問題。我有2個表有以下形式:版本9i中的Oracle SQL組合表和數據透視

人表:

ID NAME 
1 John 
2 Steve 
3 Bob 
4 Gary 

電話號碼錶:

ID TYPE NUMBER 
1 1 555-5555 
2 1 555-5556 
2 2 555-5557 
3 2 555-5558 
4 5 555-5559 

而且我希望能夠加入表如下:

ID NAME NUMBER_1 NUMBER_2 
1 John 555-5555 
2 Steve 555-5556 555-5557 
3 Bob    555-5558 
4 Gary 

請注意,有一些不同的TYPE值,但我只關心1 a ND 2.

目前的解決方案,我現在已經是加入對ID表和使用CASE語句調理上TYPE產生NUMBER_1NUMBER_2。問題是,如果我加入表格,那麼Steve會有2行。

+0

會不會是永遠兩個''每Name' –

+0

Number's'在電話號碼錶中會有每個ID不一定是2個數字。可能是0,1,2,2+。在結果表中,我只關心這些人的兩種電話號碼(他們對應於手機#和家庭# - 我不在乎傳真#等) –

回答

1

您可以使用conditional aggregation模仿pivot,因爲你只在乎1型和2:

select p.id, 
    p.name, 
    max(case when pn.type = 1 then pn.number end) number_1, 
    max(case when pn.type = 2 then pn.number end) number_2 
from person p 
    left join phonenumber pn on p.id = pn.id 
     and pn.type in (1,2) 
group by p.id, p.name 

如果null結果是一個問題,使用outer join代替。 (閱讀你的意見,他們是,所以我更新了答案)。如果您不想讓沒有電話號碼的人返回,請將其更改回inner join

注意:使用group by可確保您每人只能收到一行。 conditional aggregation將允許您返回家庭和手機號碼。


每在您的評論你的關心,這可以包括作爲一個子查詢這樣:

select * 
from sometable s 
    join (
     select p.id, 
      p.name, 
      max(case when pn.type = 1 then pn.number end) number_1, 
      max(case when pn.type = 2 then pn.number end) number_2 
     from person p 
      left join phonenumber pn on p.id = pn.id 
       and pn.type in (1,2) 
     group by p.id, p.name 
    ) t on t.id = s.id 
+0

我加入的實際表格有一噸列。有沒有辦法讓每個人得到1行,而不必明確地按照我的表中的每個變量進行「分組」? –

+0

@divide_by_zero - 使用聚合時,您在'select'列表中返回的任何未包含在聚合函數中的字段必須包含在'group by'子句中。你可以使用'動態sql'來爲你生成列表,但我建議你輸入它們。或者,您可以將它移動到只有id和電話號碼的「子查詢」,然後「加入」到其他表格 - 這樣您就不必列出其他字段。 – sgeddes

+0

@divide_by_zero - 用子查詢的例子更新了答案... – sgeddes