2012-07-13 33 views
2

是否有人知道如何基於多列表中的單個列刪除和合並重復項以創建「垂直總結」。Oracle 11g - 合併單個列副本以創建垂直總結

IE)試圖從表A

Table A: 
Person Language 
Bob English 
Sarah French 
John Chinese 
Bob French 
Sarah English 
Sarah Chinese 

Table B (RESULT): 
Person English French Chinese 
Bob  Y  Y  (null) 
Sarah  Y  Y  Y 
John  (null) (null) Y 

如何我本來想這樣做是中建表B: 從數據創建表A,然後執行以下操作:

Create table summary as 
Select person, (case when language = 'English' then 'Y') as English, (case when  language = 'French' then 'Y') as French, (case when language = 'Chinese' then 'Y') as Chinese 
From Table A; 

最後做一個選擇不同的總結表。 然而,邏輯是錯誤的,尤其是因爲在所有列中不同,所以我只想要不同的人名。

我腦海中想到的另一種選擇是創建一個只填寫人名和空列英語,法語和中文名稱的表格。然後使用更新語句通過匹配到表A來填充它們。

有沒有人知道更好的方法/我如何實現這一點。我仍然處於學習Oracle的早期階段(特別是關於循環),任何幫助都將不勝感激。

謝謝!

回答

3

Oracle有一個Decode function

但你正在尋找的是一個pivot

WITH pivot_data AS (
    SELECT Person, Language 
    FROM A 
) 
SELECT * 
FROM pivot_data 
PIVOT (
    Count(*)  --<-- pivot_clause 
    FOR Language   --<-- pivot_for_clause 
    IN ('English', 'French', 'Chinese') --<-- pivot_in_clause 
); 
0

試試這個

Create table summary 
as 
Select 
    person, 
    min(case when language = 'English' then 'Y' end) as English, 
    min(case when language = 'French' then 'Y' end) as French, 
    min(case when language = 'Chinese' then 'Y' end) as Chinese 
From 
    Table A 
group by 
    person 
0

相同的思路Sjuul,使用pivot,但是這給你你想要的Y/null值:

select * from (
    select person, language, 'Y' as flag from tablea 
) 
pivot (max(flag) for language 
    in ('English' as english, 'French' as french, 'Chinese' as chinese)); 

所以到c reate基於該新表:

create table tableb as 
select * from (
    select person, language, 'Y' as flag from tablea 
) 
pivot (max(flag) for language 
    in ('English' as english, 'French' as french, 'Chinese' as chinese)); 

Table created. 

select * from tableb order by person; 

PERSON   E F C 
--------------- - - - 
Bob    Y Y 
John    Y 
Sarah   Y Y Y 

如果tablea中的數據不會改變,你可能會更好做tableb一個視圖,以便它不出去的一步。