Please help me to the SQL Oracle 9i, convert columns to rows in group by ID.
I can't convert using UNPIVOT in oracle 9i. And I will not use UNION ALL, it's too much code to use later.
From this list:
Table:
Employees
ID | DATA 1 | DATA 2 | DATA 3 | DATA 4 |
----------------------------------------------------------
1 | 0 | 1 | 3 | 2 |
2 | 1 | 0 | 3 | 0 |
Result
ID | SOURCE | DATA |
--------------------------------------
1 | DATA 2 | 1 |
1 | DATA 4 | 2 |
1 | DATA 3 | 3 |
2 | DATA 1 | 1 |
2 | DATA 3 | 3 |
Here's a way of doing a manual unpivot:
WITH employees AS (SELECT 1 ID, 0 data1, 1 data2, 3 data3, 2 data4 FROM dual UNION ALL
SELECT 2 ID, 1 data1, 0 data2, 3 data3, 0 data4 FROM dual)
SELECT e.ID,
CASE WHEN d.id = 1 THEN 'DATA 1'
WHEN d.id = 2 THEN 'DATA 2'
WHEN d.id = 3 THEN 'DATA 3'
WHEN d.id = 4 THEN 'DATA 4'
END SOURCE,
CASE WHEN d.id = 1 THEN data1
WHEN d.id = 2 THEN data2
WHEN d.id = 3 THEN data3
WHEN d.id = 4 THEN data4
END DATA
FROM employees e
CROSS JOIN (SELECT LEVEL ID
FROM dual
CONNECT BY LEVEL <= 4 -- the number of columns to unpivot
) d
WHERE CASE WHEN d.id = 1 THEN data1
WHEN d.id = 2 THEN data2
WHEN d.id = 3 THEN data3
WHEN d.id = 4 THEN data4
END > 0
ORDER BY ID,
DATA;
ID SOURCE DATA
---------- ------ ----------
1 DATA 2 1
1 DATA 4 2
1 DATA 3 3
2 DATA 1 1
2 DATA 3 3
This uses a dummy "table" of 4 rows (since you're unpivoting 4 columns) to cross join to the main table. Then it's just a matter of outputting data1 for row 1, data2 for row 2, etc.
I've used the case statement again in the where clause, but you could do the query without the predicate in a subquery and then add the filter in the outer query if you like (e.g. select id, source, data from (select e.id, case .... ) where data > 0
)