Reputation: 3543
I have the following table:
C1 | C2 | C3
---+----+---
X1 | Y1 | Z1
X1 | Y2 | Z2
X2 | Y3 | Z3
X2 | Y4 | Z4
X3 | Y5 | Z5
X3 | Y6 | Z6
and I'd like to merge rows to get:
C1 | C2 | C3 | C4 | C5 | C6 | C7 | C8 | C9
---+----+----+---+-----+----+----+----+---
X1 | Y1 | Z1 | X2 | Y3 | Z3 | X3 | Y5 | Z5
X1 | Y2 | Z2 | X2 | Y4 | Z4 | X3 | Y6 | Z6
Is there a smart and generic way to do it ? Otherwise, I think I'm going to assign temp sequence number to each Xi, and then join on them to preserve the ordering.
My data model is perfectly fine with the 3 columns layout, but I need to output it 3 by 3 in CSV to another program.
Upvotes: 4
Views: 80
Reputation: 1269773
The only "generic" way I can think of requires knowing the X and Y values:
select max(c1) as c1, max(c2) as c2, max(c3) as c3,
max(c4) as c4, max(c5) as c5, max(c6) as c6,
max(c7) as c7, max(c8) as c8, max(c9) as c9
from ((select c1 as x, c2 as y, c1, c2, c3, NULL as c4, NULL as c5, NULL as c6, NULL as c7, NULL as c8, NULL as c9
from table
where c1 = 'x1'
) union all
(select c1 as x, c2 as y, NULL, NULL, NULL, c1 as c4, c2 as c5, c3 as c6, NULL as c7, NULL as c8, NULL as c9
from table
where c1 = 'x2'
) union all
(select c1 as x, c2 as y, NULL, NULL, NULL, NULL as c4, NULL as c5, NULL as c6, c1 as c7, c2 as c8, c3 as c9
from table
where c1 = 'x3'
)
) t
group by x, y;
In any particular database, there is probably a more generic solution, where (for instance) you don't have to guarantee that the values in col2
are different. However, this solution should work for the data as asked in the question and it is generic in the sense of being standard SQL.
Upvotes: 0
Reputation: 1986
Try this, You will join the same table three times and have to identify them by aliases.
SELECT MT1.value1 AS C1,MT1.value2 AS C2,MT1.value3 AS C3,
MT2.value1 AS C4,MT2.value2 AS C5,MT2.value3 AS C6,
MT3.value1 AS C7,MT3.value2 AS C8,MT3.value3 AS C9 FROM MY_TABLE MT1
LEFT JOIN MY_TABLE MT2 ON (MT1.id = MT2.id AND MT2.C1='X2')
LEFT JOIN MY_TABLE MT3 ON (MT2.id = MT3.id AND MT3.C1='X3')
WHERE MT1.C1='X1'
Think:
First you need to add the columns by left join. You will have 3^9 columns.
Then, add the conditions for joining only where the C1/C2/C3 differs (in X1,X2,X3)
Finally reduce the results to the first column='X1'.
Upvotes: 1