Reputation: 12592
Here is my current table
╔══════╦═══╦═══╦═══╦═════╦════╗
║ YEAR ║ A ║ B ║ C ║ ... ║ ZZ ║
╠══════╬═══╬═══╬═══╬═════╬════╣
║ 1995 ║ 1 ║ 0 ║ 1 ║ ... ║ 1 ║
║ 1996 ║ 1 ║ 1 ║ 0 ║ ... ║ 0 ║
╚══════╩═══╩═══╩═══╩═════╩════╝
And the table contains around 1000 columns. Now i need to write a code to rotate this table into a more sensible table where i represent values which are denoted as 1. So the resulting table should be like
╔══════╦════════╦═══════╗
║ YEAR ║ COLUMN ║ VALUE ║
╠══════╬════════╬═══════╣
║ 1995 ║ A ║ 1 ║
║ 1995 ║ C ║ 1 ║
║ 1995 ║ ZZ ║ 1 ║
║ 1996 ║ A ║ 1 ║
║ 1996 ║ B ║ 1 ║
╚══════╩════════╩═══════╝
So by googling bit i started creating a SQL like follows
BEGIN
DECLARE v_finished INTEGER DEFAULT 0;
DECLARE v_du **???** DEFAULT "";
DEClARE du_cursor CURSOR FOR SELECT * FROM date_usage;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET v_finished = 1;
OPEN du_cursor;
get_du: LOOP
FETCH du_cursor INTO v_du;
IF v_finished = 1 THEN
LEAVE get_du;
END IF;
SHOW v_du; <<---
END LOOP get_du;
CLOSE du_cursor;
END
But the problem is i'm not sure how to specify the v_du to be a column and I'm not sure how I'm going to read the column names. And help would be appreciated.
Thankx
Upvotes: 1
Views: 7524
Reputation: 14110
If you want to migrate your data to a new table, do it this way:
INSERT INTO new_table(`year`, `column`, `value`) SELECT year, 'A', A FROM oldTable WHERE A > 0;
INSERT INTO new_table(`year`, `column`, `value`) SELECT year, 'B', B FROM oldTable WHERE B > 0;
INSERT INTO new_table(`year`, `column`, `value`) SELECT year, 'C', C FROM oldTable WHERE C > 0;
repeat for all column names.
Upvotes: 1
Reputation: 1270463
Th easiest way is with a bunch of union all
statements:
select year, 'A' as column, A as value from table where A > 0 union all
select year, 'B' as column, B as value from table where B > 0 union all
. . .
select year, 'ZZ' as column, ZZ as value from table where ZZ > 0;
I would list the columns using information_schema.columns
and use Excel to generate the code.
The more efficient way on a large table is use to a cross join
:
select year, col,
(case when col = 'A' then A
when col = 'B' then B
. . .
when col = 'ZZ' then ZZ
end) as value
from table t cross join
(select 'A' as col union all select 'B' union all . . . select 'ZZ') cols
having value > 0;
Upvotes: 3