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

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

Related

Subtract total expenses for each month [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I'm running the following query:
select
year(date) year_date,
sum(case when month(date) = 1 then price end) January,
sum(case when month(date) = 2 then price end) February,
sum(case when month(date) = 3 then price end) March,
sum(case when month(date) = 3 then price end) May,
sum(case when month(date) = 3 then price end) April,
sum(case when month(date) = 3 then price end) June,
sum(case when month(date) = 3 then price end) July,
sum(case when month(date) = 3 then price end) August,
sum(case when month(date) = 3 then price end) September,
sum(case when month(date) = 3 then price end) October,
sum(case when month(date) = 3 then price end) November,
sum(case when month(date) = 3 then price end) December,
from orders
group by year(date)
order by year_date
I have another query to get a monthly sum of expenses:
SELECT SUM(expense) AS expenses_total FROM expenses
Any way to add this to the first query so as the end result of each month is minus the expenses?
just join those 2 tables?
select
year(dt) year_date,
sum(case when month(dt) = 1 then price end) - e.exp January,
sum(case when month(dt) = 2 then price end) - e.exp February,
sum(case when month(dt) = 3 then price end) - e.exp March,
sum(case when month(dt) = 4 then price end) - e.exp May,
sum(case when month(dt) = 5 then price end) - e.exp April,
sum(case when month(dt) = 6 then price end) - e.exp June,
sum(case when month(dt) = 7 then price end) - e.exp July,
sum(case when month(dt) = 8 then price end) - e.exp August,
sum(case when month(dt) = 9 then price end) - e.exp September,
sum(case when month(dt) = 10 then price end) - e.exp October,
sum(case when month(dt) = 11 then price end) - e.exp November,
sum(case when month(dt) = 12 then price end) - e.exp December,
e.exp
from orders o
JOIN (select SUM(expense) AS exp from expenses) e ON 1=1
group by year(dt), exp
order by year_date
value of orders table
result
fiddle

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);

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

Use date range in where clause as column names

I'm trying to dynamically use the dates within the date range of the where clause as the column names in the results. I know I can hard code this using a case/when statement:
sum(case when day(date_accessed) = 1 THEN 1 ELSE 0 END) AS `Jan 1 2014`...
Doing this every month will be cumbersome. I also know I can use php or some other scripting language to build a table, but I'm trying to accomplish all of this in mysql. Here's the query I have.
SELECT count(*) AS `Total Clicks`, day(date_accessed)
FROM Client_Activity_Log a WHERE date_accessed between '2014-01-01' AND '2014-01-31'
GROUP BY day(date_accessed);
The above query will put each date into it's own row and total it, but I'd like each date to be column. I want the results to look like this (all days of month):
Jan 1 2014 Jan 2 2014
150 200
I may have found a decent solution. Let me know if anyone has a better one:
I may have figured out the easiest solution. It won't provide the month or year in the column name but it may be as close as I get:
SELECT
SUM(CASE WHEN day(date_accessed) = 1 THEN 1 ELSE 0 END) AS '1',
SUM(CASE WHEN day(date_accessed) = 2 THEN 1 ELSE 0 END) AS `2`,
SUM(CASE WHEN day(date_accessed) = 3 THEN 1 ELSE 0 END) AS `3`,
SUM(CASE WHEN day(date_accessed) = 4 THEN 1 ELSE 0 END) AS `4`,
SUM(CASE WHEN day(date_accessed) = 5 THEN 1 ELSE 0 END) AS `5`,
SUM(CASE WHEN day(date_accessed) = 6 THEN 1 ELSE 0 END) AS `6`,
SUM(CASE WHEN day(date_accessed) = 7 THEN 1 ELSE 0 END) AS `7`,
SUM(CASE WHEN day(date_accessed) = 8 THEN 1 ELSE 0 END) AS `8`,
SUM(CASE WHEN day(date_accessed) = 9 THEN 1 ELSE 0 END) AS `9`,
SUM(CASE WHEN day(date_accessed) = 10 THEN 1 ELSE 0 END) AS `10`,
SUM(CASE WHEN day(date_accessed) = 11 THEN 1 ELSE 0 END) AS `11`,
SUM(CASE WHEN day(date_accessed) = 12 THEN 1 ELSE 0 END) AS `12`,
SUM(CASE WHEN day(date_accessed) = 13 THEN 1 ELSE 0 END) AS `13`,
SUM(CASE WHEN day(date_accessed) = 14 THEN 1 ELSE 0 END) AS `14`,
SUM(CASE WHEN day(date_accessed) = 15 THEN 1 ELSE 0 END) AS `15`,
SUM(CASE WHEN day(date_accessed) = 16 THEN 1 ELSE 0 END) AS `16`,
SUM(CASE WHEN day(date_accessed) = 17 THEN 1 ELSE 0 END) AS `17`,
SUM(CASE WHEN day(date_accessed) = 18 THEN 1 ELSE 0 END) AS `18`,
SUM(CASE WHEN day(date_accessed) = 19 THEN 1 ELSE 0 END) AS `19`,
SUM(CASE WHEN day(date_accessed) = 20 THEN 1 ELSE 0 END) AS `20`,
SUM(CASE WHEN day(date_accessed) = 21 THEN 1 ELSE 0 END) AS `21`,
SUM(CASE WHEN day(date_accessed) = 22 THEN 1 ELSE 0 END) AS `22`,
SUM(CASE WHEN day(date_accessed) = 23 THEN 1 ELSE 0 END) AS `23`,
SUM(CASE WHEN day(date_accessed) = 24 THEN 1 ELSE 0 END) AS `24`,
SUM(CASE WHEN day(date_accessed) = 25 THEN 1 ELSE 0 END) AS `25`,
SUM(CASE WHEN day(date_accessed) = 26 THEN 1 ELSE 0 END) AS `26`,
SUM(CASE WHEN day(date_accessed) = 27 THEN 1 ELSE 0 END) AS `27`,
SUM(CASE WHEN day(date_accessed) = 28 THEN 1 ELSE 0 END) AS `28`,
SUM(CASE WHEN day(date_accessed) = 29 THEN 1 ELSE 0 END) AS `29`,
SUM(CASE WHEN day(date_accessed) = 30 THEN 1 ELSE 0 END) AS `30`,
SUM(CASE WHEN day(date_accessed) = 31 THEN 1 ELSE 0 END) AS `31`
FROM Client_Activity_Log a WHERE date_accessed between '2014-01-01' AND '2014-01-31';