2013-02-05 38 views
3

我看起來像這樣的一個源表:如何將來自不同列的值分組爲一行?

enter image description here

如何使結果表看起來是這樣的。我可以在sql或java代碼中使用解決方案。

enter image description here

請,任何人都可以幫助我。 謝謝。

+0

是什麼讓你把BCDE0010放在第一排和第二排? –

+0

哪個數據庫 - SQL Server,MySQL,Oracle? – sgeddes

+0

您正在嘗試的操作稱爲數據透視表。嘗試在「數據透視表」上進行谷歌搜索 – DwB

回答

0

一個想法是使用Row_Number()作爲加入領域。像這樣:

SELECT T.Account, T.Description, T1.Value_1, T2.Value_2, T3.Value_3, T4.Value_4 
From 
    (
     SELECT Account, Description, Value_1, Value_2, Value_3, Value_4, 
      Row_number() OVER (ORDER BY (SELECT 0)) rn 
     FROM YourTable 
) T 
    LEFT JOIN (
     SELECT Account, Value_1, Row_number() OVER (ORDER BY (SELECT 0)) rn 
     FROM YourTable 
     WHERE Value_1 <> '') T1 ON T.Account = T1.Account AND T.rn = T1.rn 
    LEFT JOIN (
     SELECT Account, Value_2, Row_number() OVER (ORDER BY (SELECT 0)) rn 
     FROM YourTable 
     WHERE Value_2 <> '' 
) T2 ON T.Account = T2.Account AND T.rn = T2.rn 
    LEFT JOIN (
     SELECT Account, Value_3, Row_number() OVER (ORDER BY (SELECT 0)) rn 
     FROM YourTable 
     WHERE Value_3 <> '' 
) T3 ON T.Account = T3.Account AND T.rn = T3.rn 
    LEFT JOIN (
     SELECT Account, Value_4, Row_number() OVER (ORDER BY (SELECT 0)) rn 
     FROM YourTable 
     WHERE Value_4 <> '' 
) T4 ON T.Account = T4.Account AND T.rn = T4.rn 
WHERE T1.Value_1 IS NOT NULL 
    OR T2.VALUE_2 IS NOT NULL 
    OR T3.VALUE_3 IS NOT NULL 
    OR T4.VALUE_4 IS NOT NULL 

如果您的值存儲爲空白,那麼這應該工作。如果它們存儲爲NULL,則用IS NOT NULL替換<>''。

這是SQL Fiddle

祝你好運。

10

我認爲這樣做最簡單的方法是通過應用兩個UNPIVOTPIVOT函數來得到結果:

select account, description, 
    [value_1], [value_2], [value_3], [value_4] 
from 
(
    select account, description, col, value, 
    row_number() over(partition by account, col order by col) rn 
    from 
    (
    select [account], [description], [value_1], [value_2], [value_3], [value_4] 
    from yourtable 
) src 
    unpivot 
    (
    value 
    for col in ([value_1], [value_2], [value_3], [value_4]) 
) un 
) s 
pivot 
(
    max(value) 
    for col in ([value_1], [value_2], [value_3], [value_4]) 
) piv 

SQL Fiddle with Demo

由此也可以使用UNION ALL作爲逆透視和骨料功能和CASE表達式實現:

select account, description, 
    max(case when col = 'value_1' then value end) value_1, 
    max(case when col = 'value_2' then value end) value_2, 
    max(case when col = 'value_3' then value end) value_3, 
    max(case when col = 'value_4' then value end) value_4 
from 
(
    select account, description, col, value, 
    row_number() over(partition by account, col order by account) rn 
    from 
    (
    select [account], [description], 'value_1' col, [value_1] value 
    from yourtable 
    where [value_1] is not null 
    union all 
    select [account], [description], 'value_2' col, [value_2] value 
    from yourtable 
    where [value_2] is not null 
    union all 
    select [account], [description], 'value_3' col, [value_3] value 
    from yourtable 
    where [value_3] is not null 
    union all 
    select [account], [description], 'value_4' col, [value_4] value 
    from yourtable 
    where [value_4] is not null 
) s 
) un 
group by account, description, rn 

參見SQL Fiddle with Demo

兩者得到的結果:

| ACCOUNT | DESCRIPTION | VALUE_1 | VALUE_2 | VALUE_3 | VALUE_4 | 
---------------------------------------------------------------------- 
| A00005 | Account Desc | ABCD0081 | BCDE0010 | BKCP0010 | SMTP0010 | 
| A00005 | Account Desc | ABCD0082 | (null) | BKCP0011 | (null) | 
+0

+1爲非常乾淨的執行計劃。 – Zane

+0

+1 - 很好的答案!我站在錯誤! – sgeddes

+0

@bluefeet非常感謝,它的工作 – klipa

相關問題