2013-02-05 4 views
3

J'ai une table source qui ressemble à ceci:Comment grouper par valeurs de différentes colonnes dans une rangée?

enter image description here

Comment faire table résultat ressemble à ceci. Je pourrais utiliser la solution en sql ou en code java.

enter image description here

S'il vous plaît, quelqu'un pourrait me aider. Merci.

+0

Qu'est-ce qui vous fait mettre BCDE0010 dans la première rangée par rapport à la seconde? –

+0

Quelle base de données - SQL Server, MySQL, Oracle? – sgeddes

+0

L'opération que vous tentez s'appelle un Pivot. Essayez une recherche google sur "tableau croisé dynamique" – DwB

Répondre

0

Une idée serait d'utiliser le Row_Number() comme champ de jointure. Quelque chose comme ceci:

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 

Si vos valeurs sont stockées comme des espaces, alors cela devrait fonctionner. S'ils sont stockés en tant que valeurs NULL, remplacez <> '' par IS NOT NULL. Il s'agit d'un SQL Fiddle.

Bonne chance.

10

Je pense que la meilleure façon de le faire est à la fois en appliquant la UNPIVOT et la fonction PIVOT pour obtenir le résultat:

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 

Voir SQL Fiddle with Demo.

Cela peut aussi être fait en utilisant un UNION ALL comme UNPIVOT et une fonction d'agrégation et une expression 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 

Voir SQL Fiddle with Demo

Les deux donnent le résultat:

| 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 pour le plan d'exécution extrêmement propre. – Zane

+0

+1 - bonne réponse! Je me trompe! – sgeddes

+0

@bluefeet merci beaucoup, ça marche – klipa

Questions connexes