我正在尝试按月对两个日期过滤器之间的天数进行分组。是否可以在mysql中执行此操作。
Example : StartDate : 2012-01-19 EndDate: 2012-03-24
查询应返回按月分组的天数
Jan : 19
Feb : 29
Mar :24
Apr : 0
May : 0 etc
有没有办法做到这一点?
谢谢!
我正在尝试按月对两个日期过滤器之间的天数进行分组。是否可以在mysql中执行此操作。
Example : StartDate : 2012-01-19 EndDate: 2012-03-24
查询应返回按月分组的天数
Jan : 19
Feb : 29
Mar :24
Apr : 0
May : 0 etc
有没有办法做到这一点?
谢谢!
此查询将在有限的日期范围内(过去 1,00,000 天)为您工作。但更好的方法是用WHILE
循环编写一个单独的函数或过程。
SELECT DATE_FORMAT(_date, '%M') AS month,
COUNT(1) AS days
FROM (
SELECT CURDATE() - INTERVAL (a.a + (10 * b.a) + (100 * c.a) + (1000 * d.a) + (10000 * e.a)) DAY AS _date
FROM (SELECT 0 AS a UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS a
CROSS JOIN (SELECT 0 AS a UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS b
CROSS JOIN (SELECT 0 AS a UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS c
CROSS JOIN (SELECT 0 AS a UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS d
CROSS JOIN (SELECT 0 AS a UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS e
) a
WHERE _date BETWEEN '2012-01-19' AND '2012-03-24'
GROUP BY MONTH(_date)
ORDER BY MONTH(_date);
评论中您的问题的新答案:刚刚有一个问题,如何使用此查询对另一个表进行 JOIN。基本思想是我有一个具有 startDate 和 endDate 的 Bookings 表,并使用这些作为 _date BETWEEN 的参数,我需要找出每个月的天数。关于我如何做到这一点的任何建议?也可以在单行而不是多行中返回结果:
在此处查看SQL FIDDLE 演示:
CREATE TABLE Bookings (
start_date date DEFAULT NULL,
end_date date DEFAULT NULL
);
INSERT INTO Bookings(start_date, end_date)VALUES('2012-01-19','2012-03-24'),('2012-01-05','2012-08-21');
SELECT b.*,
(
SELECT CONCAT(DATE_FORMAT(b.start_date, '%M:'), (DATEDIFF(LAST_DAY(b.start_date), b.start_date) + 1), ',',
GROUP_CONCAT(CONCAT(DATE_FORMAT(first_day, '%M:'),days)), ',',
DATE_FORMAT(b.end_date, '%M:%d')
) AS total_days
FROM(
SELECT DATE_FORMAT(_date, '%Y-%m-01') AS first_day,
COUNT(1) AS days
FROM (
SELECT CURDATE() - INTERVAL (a.a + (10 * b.a) + (100 * c.a) + (1000 * d.a) + (10000 * e.a)) DAY AS _date
FROM (SELECT 0 AS a UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS a
CROSS JOIN (SELECT 0 AS a UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS b
CROSS JOIN (SELECT 0 AS a UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS c
CROSS JOIN (SELECT 0 AS a UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS d
CROSS JOIN (SELECT 0 AS a UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS e
) a, (SELECT @cnt := 0) b
GROUP BY YEAR(_date), MONTH(_date)
) a
WHERE first_day BETWEEN DATE_ADD(LAST_DAY(b.start_date), INTERVAL 1 DAY) AND DATE_SUB(b.end_date, INTERVAL 1 MONTH)
) total_days
FROM Bookings b
如果您遇到所选答案的问题,试试这个,它适用于 MySQL 5.7+ 默认值:
SELECT
YEAR(_date) AS year,
MONTH(_date) AS month,
COUNT(1) AS days
FROM (
SELECT CURDATE() - INTERVAL (a.a + (10 * b.a) + (100 * c.a) + (1000 * d.a) + (10000 * e.a)) DAY AS _date
FROM (SELECT 0 AS a UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS a
CROSS JOIN (SELECT 0 AS a UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS b
CROSS JOIN (SELECT 0 AS a UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS c
CROSS JOIN (SELECT 0 AS a UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS d
CROSS JOIN (SELECT 0 AS a UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS e
) a
WHERE _date BETWEEN '2018-01-01' AND '2018-10-11'
GROUP BY YEAR(_date), MONTH(_date)
ORDER BY MONTH(_date);