2013-03-20 63 views
1

,我有以下表的更復雜的版本插入多行:移調和具有不同的價值

ID | FIRST | LAST  | EMAIL 
1 | John | Doe  | [email protected] 
1 | Mack | Johnson | [email protected] 
1 | Steven | Michaels | [email protected] 
2 | Sarah | Sampson | [email protected] 
2 | Tom | Smith | [email protected] 
2 | Jane | Rogers | [email protected] 
3 | Bob | Johns | [email protected] 
3 | Kim | Lane  | [email protected] 
3 | Ron | Swanson | [email protected] 

,我想編寫一個查詢中插入該數據到另一個表看起來像這樣(的表已存在):

ID | first1 | last1 | email1    | first2 | last2 | email2    | first3 | last3 | email3 
1 | John | Doe  | [email protected]  | Mack | Johnson | [email protected] | Steven | Michaels | [email protected] 
2 | Sarah | Sampson | [email protected] | Tom | Smith | [email protected] | Jane | Rogers  | [email protected] 
3 | Bob | Johns | [email protected] | Kim | Lane  | [email protected] | Ron | Swanson  | [email protected] 

我覺得這應該很容易,但概念正在逃避我。完成此操作的最佳實踐是什麼?

也許我還應該提到,我已經寫了一個函數,可以傳遞ID,索引號和列名以返回值(即getpersoninfo(2,'1','first')返回莎拉)。

select a_id, 
    FIRST1, LAST1, EMAIL1, 
    FIRST2, LAST2, EMAIL2, 
    FIRST3, LAST3, EMAIL3 
from 
(
    select a_id, col||rn as new_col, value 
    from 
    (
    select a_id, first_name, last_name, email, 
     cast(row_number() over(partition by a_id order by a_id) as varchar2(10)) rn 
    from dump_recs_2015 
) 
    unpivot 
    (
    value 
    for col in (first_name, last_name, email) 
) 
) 
pivot 
(
    max(value) 
    for new_col in ('FIRST1' FIRST1, 'LAST1' LAST1, 'EMAIL1' EMAIL1, 
        'FIRST2' FIRST2, 'LAST2' LAST2, 'EMAIL2' EMAIL2, 
        'FIRST3' FIRST3, 'LAST3' LAST3, 'EMAIL3' EMAIL3) 
); 
+0

甲骨文的什麼版本?你是否只有每個ID有3個條目? – Taryn 2013-03-20 20:36:24

+0

11g。有些會有兩個,但最多3個 – sgd 2013-03-20 20:37:54

回答

2

由於使用的是Oracle 11g中,可以同時實現UNPIVOTPIVOT功能。

UNPIVOT將把您的列first,lastemail並將值轉換爲行。然後你就可以PIVOT新名稱First1等爲列:

select id, 
    First1, Last1, Email1, 
    First2, Last2, Email2, 
    First3, Last3, Email3 
from 
(
    select id, col||rn as new_col, value 
    from 
    (
    select id, first, last, email, 
     cast(row_number() over(partition by id order by id) as varchar2(10)) rn 
    from yourtable 
) 
    unpivot 
    (
    value 
    for col in (first, last, email) 
) 
) 
pivot 
(
    max(value) 
    for new_col in ('FIRST1' First1, 'LAST1' Last1, 'EMAIL1' Email1, 
        'FIRST2' First2, 'LAST2' Last2, 'EMAIL2' Email2, 
        'FIRST3' First3, 'LAST3' Last3, 'EMAIL3' Email3) 
) 

SQL Fiddle with Demo。這可以在INSERT語句中用於將數據加載到新表中。

編輯,根據您的列名的更改,您將使用:

select a_id, 
    First1, Last1, Email1, 
    First2, Last2, Email2, 
    First3, Last3, Email3 
from 
(
    select a_id, col||rn as new_col, value 
    from 
    (
    select a_id, first_name, last_name, email, 
     cast(row_number() over(partition by a_id order by a_id) as varchar2(10)) rn 
    from yourtable 
) 
    unpivot 
    (
    value 
    for col in (first_name, last_name, email) 
) 
) 
pivot 
(
    max(value) 
    for new_col in ('FIRST_NAME1' First1, 'LAST_NAME1' Last1, 'EMAIL1' Email1, 
        'FIRST_NAME2' First2, 'LAST_NAME2' Last2, 'EMAIL2' Email2, 
        'FIRST_NAME3' First3, 'LAST_NAME3' Last3, 'EMAIL3' Email3) 
) 

SQL Fiddle with Demo

+0

這太棒了。進行一些更改以與我的實際列名稱兼容,我的名字和姓氏即將變爲空。 – sgd 2013-03-20 20:59:47

+0

我在上面添加了我的更改。 – sgd 2013-03-20 21:02:00

+0

@sgd看到我的編輯,您只需更改'UNPIVOT'和'PIVOT'塊中使用的列名。 – Taryn 2013-03-20 21:07:08