Unpivot columns into rows in SQL
In Redshift, union all
might be the simplest method:
select date, customer, shop, 'view' as activity, view as value
from t
union all
select date, customer, shop, 'add' as activity, add as value
from t
union all
select date, customer, shop, 'buy' as activity, buy as value
from t;
You can also unpivot with case
and cross join
:
select t.date, t.customer, t.shop, x.activity,
(case x.activity when 'view' then t.view when 'add' then t.add when 'buy' then t.buy end) as value
from t cross join
(select 'view' as activity union all
select 'add' as activity union all
select 'buy' as activity
) x;
Note that aggregation is not necessary.
MySql : Convert Column data to row
select
tablename.id,
tablename.date
,SUBSTRING_INDEX(SUBSTRING_INDEX(tablename.data, ' ', numbers.n), ' ', -1) name
from
(
SELECT @row := @row + 1 as n FROM
(select 0 union all select 1 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) t,
(select 0 union all select 1 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) t1,
(select 0 union all select 1 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) t2,
(SELECT @row:=0) r
) numbers INNER JOIN Table1 tablename
on CHAR_LENGTH(tablename.data)
-CHAR_LENGTH(REPLACE(tablename.data, ' ', ''))>=numbers.n-1
order by
id, n
Check link for output
http://sqlfiddle.com/#!9/fa0dcb/1
EXPLANATION:
First go through the inner query i.e.
select 0
union all
select 1
union all
select 3
union all
select 4
union all
select 5
union all
select 6
union all
select 6
union all
select 7
union all
select 8
union all
select 9
This will generate a table of 10 rows with 10 numbers.
Now the other query :
SELECT @row := @row + 1 as n FROM
(select 0 union all select 1 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) t,
(select 0 union all select 1 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) t1
Since above query is generating row numbers from below table 't' and table 't1' which is separated by ',' means that they are producing Cartesian product of their total rows.
For example: t have 10 rows and t1 also have 10 rows so, there Cartesian product produces 100 rows. So @row variable incremented 100 times and gives 100 rows of 100 numbers from 1 to 100.
The below query:
SUBSTRING_INDEX(SUBSTRING_INDEX(tablename.data, ' ', numbers.n), ' ', -1)
this one will take "a b c d e f g h" one by one.
For example:
take numbers.n = 1
then inner substring_index will find index of first space and will return string before that index i.e. 'a'
and then outer substring_index will find the space from the end of the resulting string and will give the last character from the string i.e. 'a'
.
Now if you
take numbers.n = 2
then inner substring_index will find index of first space and will return string before that index i.e. 'a b'
and then outer substring_index will find the space from the end of the resulting string and will give the last character from the string i.e. 'b'
Always try to breakdown the query like this and you will able to understand the query in simpler way.
mySQL how to unpivot dynamic columns
Sadly, mysql does not have an UNPIVOT
function.
Your best option is the UNION ALL
solution, like :
SELECT region, 'M07' AS month, M07 AS qty from stat
UNION ALL
SELECT region, 'M08', M08 AS from stat
UNION ALL
SELECT region, 'M09', M09 AS from stat
It would be possible to create a piece of SQL code (as a stored procedure for example) that would generate this SQL query dynamically by first querying the INFORMATION_SCHEMA
to retrieve the columns names, and using the results to build the query text.
UNPIVOT mysql data to other table
You need to UNPIVOT
your data. MySQL doesn't have a built in function to do that so you'll need to use multiple queries.
INSERT INTO `monthlydata` (`id`, `year`, `monthName`, `stat_id`, `cat_id`, `data`) VALUES
SELECT id, year, 'January', stat_id, cat_id, January
FROM monthly WHERE monthName = 'January'
UNION ALL
SELECT id, year, 'February', stat_id, cat_id, February
FROM monthly WHERE monthName = 'February'
UNION ALL
SELECT id, year, 'March', stat_id, cat_id, March
FROM monthly WHERE monthName = 'March'
.....
ID
column here might cause issues. Depending on how you have defined it. If it is auto generated then you can remove it from the INSERT and let it be auto generated. Since you'll have rows for all months with same ID
, you need to handle that scenario.
Related Topics
How to Use Group by to Concatenate Strings in SQL Server
How to Insert Multiple Rows At a Time in an Sqlite Database
How to Reset Auto_Increment in MySQL
Why Does Oracle 9I Treat an Empty String as Null
How to Select the Nth Row in a SQL Database Table
MySQL Query Group by Day/Month/Year
Join Tables With Sum Issue in MySQL
What's the Best Practice For Primary Keys in Tables
How to Spool to a CSV Formatted File Using Sqlplus
How to Select the First Day of a Month in Sql
MySQL Update Column With Value from Another Table