how to reuse the resultset in mysql query - mysql

I have result set like this after executing "select * from temp"
id | Month | value1 | value2 |
------------------------------
1 | Apr | 100 | 150
2 | May | 50 | 75
3 | Jan | 50 | 75
5 | Feb | 50 | 75
6 | mar | 50 | 75
I want to change it to column to rows like pivot table.
i used case when statement to change it.
select
'value1' as Field,
SUM(CASE
WHEN dc.month = 'January' THEN dc.value1
ELSE ''
END) AS January,
SUM(CASE
WHEN dc.month = 'February' THEN dc.value1
ELSE ''
END) AS February,
SUM(CASE
WHEN dc.month = 'March' THEN dc.value1
ELSE ''
END) AS March
SUM(CASE
WHEN dc.month = 'April' THEN dc.value1
ELSE ''
END) AS April,
SUM(CASE
WHEN dc.month = 'May' THEN dc.value1
ELSE ''
END) AS May
from
(select
* from
temp)dc
Field | Jan | Feb | Mar | Apr | May
-------------------------------------
Value1 | 50 | 50 | 50 | 100 | 50
I want to get same result set for value2 in same query without using UNION. Because temp table has lot of data's.
Field | Jan | Feb | Mar | Apr | May
-------------------------------------
Value1 | 50 | 50 | 50 | 100 | 50
Value1 | 75 | 75 | 75 | 150 | 75

This solution uses a union, but only to create "fake" rows to represent each value* column, and then joins and groups by those rows:
SELECT
`field`,
SUM(CASE
WHEN dc.month = 'Jan' THEN
CASE `field`
WHEN 'value1' THEN dc.value1
WHEN 'value2' THEN dc.value2
END
ELSE ''
END) AS January,
SUM(CASE
WHEN dc.month = 'Feb' THEN
CASE `field`
WHEN 'value1' THEN dc.value1
WHEN 'value2' THEN dc.value2
END
ELSE ''
END) AS February,
SUM(CASE
WHEN dc.month = 'Mar' THEN
CASE `field`
WHEN 'value1' THEN dc.value1
WHEN 'value2' THEN dc.value2
END
ELSE ''
END) AS March,
SUM(CASE
WHEN dc.month = 'Apr' THEN
CASE `field`
WHEN 'value1' THEN dc.value1
WHEN 'value2' THEN dc.value2
END
ELSE ''
END) AS April,
SUM(CASE
WHEN dc.month = 'May' THEN
CASE `field`
WHEN 'value1' THEN dc.value1
WHEN 'value2' THEN dc.value2
END
ELSE ''
END) AS May
FROM
(SELECT
* FROM temp
)dc
INNER JOIN (
SELECT 'value1' AS `field`
UNION SELECT 'value2'
) AS value_columns
GROUP BY `field`

If its just 2 colums i.e. value1 and value2 then you can use UNION as DEMO
select
'value1' as Field,
SUM(
CASE
WHEN dc.month = 'Jan' THEN dc.value1
ELSE ''
END) AS January,
SUM(
CASE
WHEN dc.month = 'Feb' THEN dc.value1
ELSE ''
END) AS February,
SUM(
CASE
WHEN dc.month = 'Mar' THEN dc.value1
ELSE ''
END) AS March,
SUM(
CASE
WHEN dc.month = 'Apr' THEN dc.value1
ELSE ''
END) AS April,
SUM(
CASE
WHEN dc.month = 'May' THEN dc.value1
ELSE ''
END)AS May
from
temp dc
UNION
select
'value2' as Field,
SUM(
CASE
WHEN dc.month = 'Jan' THEN dc.value2
ELSE ''
END) AS January,
SUM(
CASE
WHEN dc.month = 'Feb' THEN dc.value2
ELSE ''
END) AS February,
SUM(
CASE
WHEN dc.month = 'Mar' THEN dc.value2
ELSE ''
END) AS March,
SUM(
CASE
WHEN dc.month = 'Apr' THEN dc.value2
ELSE ''
END) AS April,
SUM(
CASE
WHEN dc.month = 'May' THEN dc.value2
ELSE ''
END)AS May
from temp dc

Related

Transpose row to columns in SQL/PHP

I fetched the following data:
MONTH | TOTAL
-------------------------
Jan | 100
Feb | 200
Mar | 300
Using this query:
$query = "SELECT DATE_FORMAT(date,'%b') AS MONTH, SUM(col1+col2) AS TOTAL FROM myTable GROUP BY YEAR(date),MONTH(date)";
How can I edit the above query or re-write to get the following result:
JAN | FEB | MAR
-------------------------
100 | 200 | 300
I have gone through almost all the the other similar posts. However, sql transposing, to me, is very confusing. Any input is much appreciated!
You can use conditional aggregation. The following will work in either SQL Server or MySQL:
select year(date),
sum(case when month(date) = 1 then col1 + col2 else 0 end) as jan,
sum(case when month(date) = 2 then col1 + col2 else 0 end) as feb,
sum(case when month(date) = 3 then col1 + col2 else 0 end) as mar
from mytable
group by year(date)
order by year(date);
EDIT (regarding the comment):
select year(date),
sum(case when month(date) = 1 then val else 0 end) as jan,
sum(case when month(date) = 2 then val else 0 end) as feb,
sum(case when month(date) = 3 then val else 0 end) as mar
from (select t.*, (col1 + col2) as val
from mytable
) t
group by year(date)
order by year(date);

Select and create month row and count the data - MySQL

I had a problem. I have the data like below:
-----------------------
| last_login_dt |
-----------------------
| 2015-08-11 08:06:36 |
| 2015-06-10 22:06:43 |
| 2015-06-11 08:06:58 |
| 2015-09-11 08:06:45 |
-----------------------
So far, I managed to count this kind of data and turn into this using below statement:
SELECT DATE_FORMAT(last_login_dt,'%m/%Y') as `month`,
count(last_login_dt) as `total_visits` from public_user
WHERE DATE_FORMAT(last_login_dt,'%Y') = YEAR(CURDATE())
group by DATE_FORMAT(last_login_dt,'%m/%Y')
order by `month` asc;
----------------------------
| month | total_visits |
----------------------------
| 06/2015 | 2 |
| 08/2015 | 1 |
| 09/2015 | 1 |
----------------------------
The problem is, how to turn the result like below. Instead this table only have 4 rows of data, how to create a jan, feb, mar, apr ... row with total_visit = 0:
---------------------
| Month | Total |
---------------------
| Jan | 0 |
| Feb | 0 |
| Mar | 0 |
| Apr | 0 |
| May | 0 |
| Jun | 2 |
| Jul | 0 |
| Aug | 1 |
| Sep | 1 |
| Oct | 0 |
| Nov | 0 |
| Dis | 0 |
---------------------
I use your own query because it's working and I modified it a bit. Consider the query below:
SELECT `month`, `total_visits` FROM
(
SELECT * FROM
(
SELECT '01' AS `month_num`, 'Jan' As `month`, 0 AS `total_visits`
UNION
SELECT '02' AS `month_num`, 'Feb' AS `month`, 0 AS `total_visits`
UNION
SELECT '03' AS `month_num`, 'Mat' AS `month`, 0 AS `total_visits`
UNION
SELECT '04' AS `month_num`, 'Apr' AS `month`, 0 AS `total_visits`
UNION
SELECT '05' AS `month_num`, 'May' AS `month`, 0 AS `total_visits`
UNION
SELECT '06' AS `month_num`, 'Jun' AS `month`, 0 AS `total_visits`
UNION
SELECT '07' AS `month_num`, 'Jul' AS `month`, 0 AS `total_visits`
UNION
SELECT '08' AS `month_num`, 'Aug' AS `month`, 0 AS `total_visits`
UNION
SELECT '09' AS `month_num`, 'Sep' AS `month`, 0 AS `total_visits`
UNION
SELECT '10' AS `month_num`, 'Oct' AS `month`, 0 AS `total_visits`
UNION
SELECT '11' AS `month_num`, 'Nov' AS `month`, 0 AS `total_visits`
UNION
SELECT '12' AS `month_num`, 'Dec' AS `month`, 0 AS `total_visits`
UNION
SELECT DATE_FORMAT(last_login_dt,'%m') as `month_num`, DATE_FORMAT(last_login_dt,'%b') as `month`,
count(last_login_dt) as `total_visits` from public_user
WHERE DATE_FORMAT(last_login_dt,'%Y') = YEAR(CURDATE())
group by DATE_FORMAT(last_login_dt,'%m/%Y')
order by `total_visits` desc
) AS tmp
GROUP BY `month`
) AS total_visits
ORDER BY `month_num`;
It results in:
---------------------
| Month | Total |
---------------------
| Jan | 0 |
| Feb | 0 |
| Mar | 0 |
| Apr | 0 |
| May | 0 |
| Jun | 2 |
| Jul | 0 |
| Aug | 1 |
| Sep | 1 |
| Oct | 0 |
| Nov | 0 |
| Dis | 0 |
---------------------
I first created the table that displays the months and its total_visits (which is obviously 0). Then I unite your query to the derived table I created. I also added the month_num field for the sole purpose of sorting the data by month although it's not shown in the final result.
You're almost there. Try this %b in your date format string:
mysql> SELECT DATE_FORMAT(NOW(), '%b');
+--------------------------+
| DATE_FORMAT(NOW(), '%b') |
+--------------------------+
| Jun |
+--------------------------+
1 row in set (0.00 sec)
mysql>
The format for the month name is %b.
So I think you must change the %m to %b.
Try this sql if it works:
SELECT DATE_FORMAT(last_login_dt,'%b/%Y') as `month`,
count(last_login_dt) as `total_visits` from public_user
WHERE DATE_FORMAT(last_login_dt,'%Y') = YEAR(CURDATE())
group by DATE_FORMAT(last_login_dt,'%m/%Y')
order by `month` asc;
UPDATE AS OF 06/11/2015 11:57 AM GMT+8
We cannot display list of months in rows, but rather I used to make a derived column to display months and in total_visits on the row. I used case for the query to check if date is for the specific month.
SELECT
CASE WHEN DATE_FORMAT(last_login_dt,'%m') = '01' THEN count(last_login_dt) ELSE '0' END AS Jan,
CASE WHEN DATE_FORMAT(last_login_dt,'%m') = '02' THEN count(last_login_dt) ELSE '0' END AS Feb,
CASE WHEN DATE_FORMAT(last_login_dt,'%m') = '03' THEN count(last_login_dt) ELSE '0' END AS Mar,
CASE WHEN DATE_FORMAT(last_login_dt,'%m') = '04' THEN count(last_login_dt) ELSE '0' END AS Apr,
CASE WHEN DATE_FORMAT(last_login_dt,'%m') = '05' THEN count(last_login_dt) ELSE '0' END AS May,
CASE WHEN DATE_FORMAT(last_login_dt,'%m') = '06' THEN count(last_login_dt) ELSE '0' END AS Jun,
CASE WHEN DATE_FORMAT(last_login_dt,'%m') = '07' THEN count(last_login_dt) ELSE '0' END AS Jul,
CASE WHEN DATE_FORMAT(last_login_dt,'%m') = '08' THEN count(last_login_dt) ELSE '0' END AS Aug,
CASE WHEN DATE_FORMAT(last_login_dt,'%m') = '09' THEN count(last_login_dt) ELSE '0' END AS Sep,
CASE WHEN DATE_FORMAT(last_login_dt,'%m') = '10' THEN count(last_login_dt) ELSE '0' END AS Oct,
CASE WHEN DATE_FORMAT(last_login_dt,'%m') = '11' THEN count(last_login_dt) ELSE '0' END AS Nov,
CASE WHEN DATE_FORMAT(last_login_dt,'%m') = '12' THEN count(last_login_dt) ELSE '0' END AS `Dec`
FROM public_user;
The result will be:
------------------------------------------------------------------------
| Jan | Feb | Mar| Apr| May| Jun| Jul| Aug | Sep| Oct | Nov | Dec |
------------------------------------------------------------------------
| 0 | 0 | 0 | 0 | 0 | 2 | 0 | 1 | 1 | 0 | 0 | 0 |
------------------------------------------------------------------------

How to do Pivot in MySQL where only one column is the base of the query

I saw a lot of ways on how to do pivot in MySQL but I can't relate it in my situation.
My situation is, I have a column called date_of_mem in tbl_members. I need to count how many member did register in that particular month and year.
For Example:
I have a table called tbl_members with column named id,fname,mname,lname and date_of_mem and so forth.
Now, I want to have this result:
Year | January | February | March | April | May | June | July ...
2013 | 100 | 250 | 50 | 60 | 300 | 280 | 125 ...
2014 | 101 | 240 | 20 | 40 | 200 | 180 | 145 ...
How to do this in MySQL.
Thanks in advance...
select year(date_of_mem) as yr,
sum(case when month(date_of_mem) = 1 then 1 else 0 end) as january,
sum(case when month(date_of_mem) = 2 then 1 else 0 end) as february,
sum(case when month(date_of_mem) = 3 then 1 else 0 end) as march,
sum(case when month(date_of_mem) = 4 then 1 else 0 end) as april,
sum(case when month(date_of_mem) = 5 then 1 else 0 end) as may,
sum(case when month(date_of_mem) = 6 then 1 else 0 end) as june,
sum(case when month(date_of_mem) = 7 then 1 else 0 end) as july,
sum(case when month(date_of_mem) = 8 then 1 else 0 end) as august,
sum(case when month(date_of_mem) = 9 then 1 else 0 end) as september,
sum(case when month(date_of_mem) = 10 then 1 else 0 end) as october,
sum(case when month(date_of_mem) = 11 then 1 else 0 end) as november,
sum(case when month(date_of_mem) = 12 then 1 else 0 end) as december
from tbl_members
group by year(date_of_mem)

mysql compute no of leaves thru months

I have a table
Name duration date_leave_from date_leave_to
John 1 2015-03-01 2015-03-01
Doe .5 2015-03-02 2015-03-02
John .5 2015-03-02 2015-03-02
Doe 1 2015-01-03 2015-01-03
Doe 1 2015-02-04 2015-02-04
I would like to get the data in the following format:
Name || Jan || Feb || March || April .. to DEC
John || 1 || 0 || 1.5 || 0
Doe || 0 || 1 || .5 || 0
You can do like this:
SELECT name,
SUM(CASE WHEN MONTH(from_date) = '1' THEN duration else 0 END) AS Jan,
SUM(CASE WHEN MONTH(from_date) = '2' THEN duration else 0 END) AS Feb,
SUM(CASE WHEN MONTH(from_date) = '3' THEN duration else 0 END) AS March,
SUM(CASE WHEN MONTH(from_date) = '4' THEN duration else 0 END) AS April,
SUM(CASE WHEN MONTH(from_date) = '5' THEN duration else 0 END) AS May,
SUM(CASE WHEN MONTH(from_date) = '6' THEN duration else 0 END) AS Jun,
SUM(CASE WHEN MONTH(from_date) = '7' THEN duration else 0 END) AS Jul,
SUM(CASE WHEN MONTH(from_date) = '8' THEN duration else 0 END) AS Aug,
SUM(CASE WHEN MONTH(from_date) = '9' THEN duration else 0 END) AS Sep,
SUM(CASE WHEN MONTH(from_date) = '10' THEN duration else 0 END) AS Oct,
SUM(CASE WHEN MONTH(from_date) = '11' THEN duration else 0 END) AS Nov,
SUM(CASE WHEN MONTH(from_date) = '12' THEN duration else 0 END) AS December
FROM test
GROUP BY name
This is the fiddle

How can I GROUP BY more than one row/column?

I'm looking for a way to group more than one column in mysql.
The table is pretty much:
Customer, Product, Date
Joe, Apple, 2011-01-01
Henry, Banana, 2011-05-26
Sally, Peach, 2011-06-02
Jane, Strawberry, 2010-06-25
What I wanna do is count the NUMBER of Produkts each customer bought and group that by the month of the year.
So it would look like.
COUNT(Product) | January | February | March ....... | Total
If I just use GROUP BY product, MONTH(date) I get
Banana, January, 2
Banana, February, 3
Banana, March, 1
and so on.
Is there a way to do this, so that I get as many rows as I have distinct products and then a column for each month?
I'm really trying NOT to do this lateron in PHP because it get's incredibly slow.
Thanks a lot, already!
SELECT Product,
SUM(CASE WHEN MONTH(date) = 1 THEN 1 ELSE 0 END) Jan,
SUM(CASE WHEN MONTH(date) = 2 THEN 1 ELSE 0 END) Feb,
SUM(CASE WHEN MONTH(date) = 3 THEN 1 ELSE 0 END) Mar,
SUM(CASE WHEN MONTH(date) = 4 THEN 1 ELSE 0 END) Apr,
SUM(CASE WHEN MONTH(date) = 5 THEN 1 ELSE 0 END) May,
SUM(CASE WHEN MONTH(date) = 6 THEN 1 ELSE 0 END) Jun,
SUM(CASE WHEN MONTH(date) = 7 THEN 1 ELSE 0 END) Jul,
SUM(CASE WHEN MONTH(date) = 8 THEN 1 ELSE 0 END) Aug,
SUM(CASE WHEN MONTH(date) = 9 THEN 1 ELSE 0 END) Sep,
SUM(CASE WHEN MONTH(date) = 10 THEN 1 ELSE 0 END) Oct,
SUM(CASE WHEN MONTH(date) = 11 THEN 1 ELSE 0 END) Nov,
SUM(CASE WHEN MONTH(date) = 12 THEN 1 ELSE 0 END) Dec,
COUNT(date) Total
FROM
MyTable
GROUP BY
product