2013-02-05 36 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

相关问题