简体   繁体   中英

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM