Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Group By Year and Month in MySQL

Tags:

I would like to measure the count of ID and ATTRIBUTE from the source table and present the data as shown in the "Desired Report" below. I am using MySQL.

Source:

ID  |  DATE        |  ATTRIBUTE -------------------------------- 1   |  2012-01-14  |   XYZ 2   |  2012-03-14  |    3   |  2012-03-15  |   XYZ 4   |  2012-04-24  |   ABC 5   |  2012-04-10  |    6   |  2012-05-11  |   ABC 

Desired Reports:

Count of Attribute

   YEAR | JAN | FEB | MAR | APR | MAY | JUN | JUL | AUG | SEP | OCT | NOV | DEC    ---------------------------------------------------------------------------    2010 |  0  |  0  |  0  |  0  |  0  |  0  |  0  |  0  |  0  |  0  |  0  |  0     2011 |  0  |  0  |  0  |  0  |  0  |  0  |  0  |  0  |  0  |  0  |  0  |  0     2012 |  0  |  0  |  0  |  0  |  0  |  0  |  0  |  0  |  0  |  0  |  0  |  0  

Count of ID

   YEAR | JAN | FEB | MAR | APR | MAY | JUN | JUL | AUG | SEP | OCT | NOV | DEC    ---------------------------------------------------------------------------    2010 |  0  |  0  |  0  |  0  |  0  |  0  |  0  |  0  |  0  |  0  |  0  |  0     2011 |  0  |  0  |  0  |  0  |  0  |  0  |  0  |  0  |  0  |  0  |  0  |  0     2012 |  0  |  0  |  0  |  0  |  0  |  0  |  0  |  0  |  0  |  0  |  0  |  0  

Percentage Complete ( Count of Attribute / Count of ID )

   YEAR | JAN | FEB | MAR | APR | MAY | JUN | JUL | AUG | SEP | OCT | NOV | DEC    ---------------------------------------------------------------------------    2010 |  0  |  0  |  0  |  0  |  0  |  0  |  0  |  0  |  0  |  0  |  0  |  0     2011 |  0  |  0  |  0  |  0  |  0  |  0  |  0  |  0  |  0  |  0  |  0  |  0     2012 |  0  |  0  |  0  |  0  |  0  |  0  |  0  |  0  |  0  |  0  |  0  |  0  

Here's the code I have so far. Thanks! And Also keep in mind, I need to extract the Month from the date field in my data but not sure how. Thanks.

SELECT YEAR(document_filing_date),MONTH(document_filing_date),COUNT(aif_id) FROM (a_aif_remaining) GROUP BY YEAR(document_filing_date),MONTH(document_filing_date); 

Suggested answer doesn't work!! Not sure why, here is the error I get:

"#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ' COUNT(CASE WHEN MONTH(document_filing_date) = 1 THEN aif_id END) AS Jan, CO' at line 1"  SELECT YEAR(document_filing_date,   COUNT(CASE WHEN MONTH(document_filing_date) = 1 THEN aif_id END) AS Jan,   COUNT(CASE WHEN MONTH(document_filing_date) = 2 THEN aif_id END) AS Feb,   COUNT(CASE WHEN MONTH(document_filing_date) = 3 THEN aif_id END) AS Mar,   COUNT(CASE WHEN MONTH(document_filing_date) = 4 THEN aif_id END) AS Apr,   COUNT(CASE WHEN MONTH(document_filing_date) = 5 THEN aif_id END) AS May,   COUNT(CASE WHEN MONTH(document_filing_date) = 6 THEN aif_id END) AS Jun,   COUNT(CASE WHEN MONTH(document_filing_date) = 7 THEN aif_id END) AS Jul,   COUNT(CASE WHEN MONTH(document_filing_date) = 8 THEN aif_id END) AS Aug,   COUNT(CASE WHEN MONTH(document_filing_date) = 9 THEN aif_id END) AS Sep,   COUNT(CASE WHEN MONTH(document_filing_date) = 10 THEN aif_id END) AS Oct,   COUNT(CASE WHEN MONTH(document_filing_date) = 11 THEN aif_id END) AS Nov,   COUNT(CASE WHEN MONTH(document_filing_date) = 12 THEN aif_id END) AS Dec, FROM a_aif_remaining GROUP BY YEAR(document_filing_date); 
like image 827
Ben Avatar asked Dec 24 '12 10:12

Ben


2 Answers

This query will count all the rows, and will also count just the rows where Attribute is not null, grouping by year and month in rows:

SELECT   Year(`date`),   Month(`date`),   Count(*) As Total_Rows,   Count(`Attribute`) As Rows_With_Attribute FROM your_table GROUP BY Year(`date`), Month(`date`) 

(this because Count(*) counts all the rows, Count(Attibute) counts all the rows where Attribute is not null)

If you need your table in PIVOT, you can use this to count only the rows where Attribute is not null:

SELECT   Year(`date`),   Count(case when month(`date`)=1 then `Attribute` end) As Jan,   Count(case when month(`date`)=2 then `Attribute` end) As Feb,   Count(case when month(`date`)=3 then `Attribute` end) As Mar,   ... FROM your_table GROUP BY Year(`date`) 

And this to count all the rows:

SELECT   Year(`date`),   Count(case when month(`date`)=1 then id end) As Jan,   Count(case when month(`date`)=2 then id end) As Feb,   Count(case when month(`date`)=3 then id end) As Mar,   ... FROM your_table GROUP BY Year(`date`) 

(or, instead of counting id, you can use Sum(Month(date)=1) like in kander's answer). Of course you can combine both queries into this:

SELECT   Year(`date`),   Count(case when month(`date`)=1 then id end) As Jan_Tot,   Count(case when month(`date`)=1 then `Attribute` end) As Jan_Attr,   Count(case when month(`date`)=2 then id end) As Feb_Tot,   Count(case when month(`date`)=2 then `Attribute` end) As Feb_Attr,   Count(case when month(`date`)=3 then id end) As Mar_Tot,   Count(case when month(`date`)=3 then `Attribute` end) As Mar_Attr,   ... FROM your_table GROUP BY Year(`date`) 
like image 138
fthiella Avatar answered Sep 22 '22 14:09

fthiella


I've come up with the following, but have a feeling that there might be a more efficient way to go about this...

select year(`date`) as 'YEAR', sum(month(`date`) = 1) as 'JAN', sum(month(`date`) = 2) as 'FEB', sum(month(`date`) = 3) as 'MAR',     -- Repeat until december FROM `source` WHERE `ATTRIBUTE` = 'XYZ' GROUP BY 1; 
like image 38
kander Avatar answered Sep 22 '22 14:09

kander