我正在努力解决这个问题。
我有一个包含3列的表:
id, startDate, endDate
1, 2014-01-01, 2014-02-02
2, 2014-04-03, NULL
3, 2014-02-02, 2014-05-03
现在我想要计算所有具有特殊条件的ID: 例如月份可能:
SELECT COUNT(*) FROM Table WHERE startDate <= "2014-05-31" and (endDate >= "2014-05-01" or endDate is NULL)
我如何通过分组年份和月份来实现这一目标?
startDate应始终为&lt; = lastDayofGivenMonth和endDate&gt; = firstDayofGivenMonth或Null
结果应如下所示:
year, month, count
2014, 01, 1
2014, 02, 2
2014, 03, 2
2014, 04, 2
2014, 05, 2
2014, 06, 1
...
感谢您的帮助!
史蒂夫
答案 0 :(得分:0)
首先,创建一个包含您关注的所有月份的表格:
CREATE TABLE months (
year INTEGER,
month INTEGER,
start DATE,
end DATE,
PRIMARY KEY (year, month)
);
INSERT INTO months VALUES (2014, 1, '2014-01-01', '2014-01-31'), (2014, 2, '2014-02-01', '2014-02-28'), (2014, 3, '2014-03-01', '2014-03-31'), ...;
然后将此表与您的事件表联系起来:
SELECT m.year, m.month, COUNT(t.id) AS count
FROM months AS m
LEFT JOIN YourTable AS t
ON (startDate BETWEEN m.start AND m.end)
OR (endDate IS NOT NULL
AND m.start BETWEEN startDate AND endDate)
GROUP BY year, month
获得了日期范围比较
答案 1 :(得分:0)
我的结果集与你的结果不符,但你是否正在寻找类似的东西...
我有一个整数的实用程序表(0-9)。我可以用它来构建一个简单的月历......
SELECT '2014-01-01' + INTERVAL i2.i*10+i1.i MONTH dt FROM ints i1,ints i2 HAVING dt < '2015-01-01';
+------------+
| dt |
+------------+
| 2014-01-01 |
| 2014-02-01 |
| 2014-03-01 |
| 2014-04-01 |
| 2014-05-01 |
| 2014-06-01 |
| 2014-07-01 |
| 2014-08-01 |
| 2014-09-01 |
| 2014-10-01 |
| 2014-11-01 |
| 2014-12-01 |
+------------+
有了这个,我可以做以下......
DROP TABLE IF EXISTS my_table;
CREATE TABLE my_table
(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
,startDate DATE NOT NULL
,endDate DATE NULL
);
INSERT INTO my_table VALUES
(1, '2014-01-01', '2014-02-02'),
(2, '2014-04-03', NULL),
(3, '2014-02-02', '2014-05-03');
SELECT DATE_FORMAT(x.dt,'%Y-%m') yearmonth
, COUNT(y.id) total
FROM
( SELECT '2014-01-01' + INTERVAL i2.i*10+i1.i MONTH dt FROM ints i1,ints i2 HAVING dt < '2015-01-01' ) x
LEFT
JOIN my_table y
ON DATE_FORMAT(x.dt,'%Y-%m') >= DATE_FORMAT(startdate,'%Y-%m')
AND (DATE_FORMAT(x.dt,'%Y-%m') <= DATE_FORMAT(enddate,'%Y-%m') OR y.enddate IS NULL)
GROUP
BY yearmonth;
+-----------+-------+
| yearmonth | total |
+-----------+-------+
| 2014-01 | 1 |
| 2014-02 | 2 |
| 2014-03 | 1 |
| 2014-04 | 2 |
| 2014-05 | 2 |
| 2014-06 | 1 |
| 2014-07 | 1 |
| 2014-08 | 1 |
| 2014-09 | 1 |
| 2014-10 | 1 |
| 2014-11 | 1 |
| 2014-12 | 1 |
+-----------+-------+
答案 2 :(得分:0)
您需要一个日期范围(年,月)进行测试。您可以通过不同方式创建此范围,例如:
SELECT Y, M, DATE_ADD(MAKEDATE(Y, 1), INTERVAL M -1 MONTH) AS FirstDay, LAST_DAY(DATE_ADD(MAKEDATE(Y, 1), INTERVAL M -1 MONTH)) AS LastDay
FROM
(select 2013 as Y union all select 2014 union all select 2015) years
cross join
(select 1 as M 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 union all select 10 union all select 11 union all select 12) months
然后它将是一个简单的连接和分组:
SELECT Y, M, count(d.id)
FROM (
SELECT Y, M, DATE_ADD(MAKEDATE(Y, 1), INTERVAL M -1 MONTH) AS FirstDay, LAST_DAY(DATE_ADD(MAKEDATE(Y, 1), INTERVAL M -1 MONTH)) AS LastDay
FROM
(select 2013 as Y union all select 2014 union all select 2015) years
cross join
(select 1 as M 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 union all select 10 union all select 11 union all select 12) months
) YM
LEFT JOIN dates d ON startDate <= YM.LastDay AND (endDate IS NULL OR endDate >= YM.FirstDay)
GROUP BY Y, M