我有一个事件表,每个事件都有一个给定的开始和结束日期。
CREATE TABLE dataset (
id int(11) unsigned NOT NULL AUTO_INCREMENT,
event varchar(64) NOT NULL DEFAULT '',
valid_from date DEFAULT NULL,
valid_to date DEFAULT NULL,
PRIMARY KEY (id)
);
INSERT INTO dataset (event, valid_from, valid_to) VALUES
('Test1', '2014-12-01', '2014-12-01'),
('Test2', '2014-12-02', '2014-12-02'),
('Test3', '2014-12-03', '2014-12-03'),
('Test4', '2014-12-04', '2014-12-04'),
('Test5', '2014-12-05', '2014-12-05'),
('Test6', '2014-12-01', '2014-12-01'),
('Test7', '2014-12-01', '2014-12-07');
我需要查询帮助才能获得给定日期范围内的最大并发事件数。如果开始日期和结束日期与此查询的预期结果相同:
SET @d1 = '2014-12-01';
SET @d2 = '2014-12-01';
SELECT COUNT(*) as valid_events FROM dataset WHERE @d2 >= valid_from AND valid_to >= @d1;
这将返回3,它在12月1日与Test1,Test6和Test7匹配。但如果我延长范围,它就不再为我工作了:
SET @d1 = '2014-12-01';
SET @d2 = '2014-12-07';
SELECT COUNT(*) as valid_events FROM dataset WHERE @d2 >= valid_from AND valid_to >= @d1;
这会返回7,因为所有事件都与开始日期和结束日期重叠,但我希望它们只有在彼此重叠时才会被计算。
Test1 Test2 Test3 Test4 Test5 Test6 Test7 Result
2014-12-01 X X X 3
2014-12-02 X X 2
2014-12-03 X X 2
2014-12-04 X X 2
2014-12-05 X X 2
2014-12-06 X 1
2014-12-07 X 1
因此,如果我在12月1日和7日之间请求最大并发事件数量,我希望得到3而不是7的结果。
答案 0 :(得分:0)
在其中一个开始日期发生最大并发事件数。因此,您可以通过一些连接和聚合来执行此操作:
select d.valid_from, count(*) as numoverlaps
from (select distinct d.valid_from from dataset d
) d join
dataset d2
on d.valid_from >= d2.valid_from and d.valid_from <= d2.valid_to
group by d.valid_from;
您可以通过添加order by
和limit
:
select d.*
from (select d.valid_from, count(*) as numoverlaps
from (select distinct d.valid_from from dataset d
) d join
dataset d2
on d.valid_from >= d2.valid_from and d.valid_from <= d2.valid_to
group by d.valid_from
) d
order by numoverlaps desc
limit 1;
答案 1 :(得分:0)
SELECT * FROM calendar WHERE dt BETWEEN '2014-11-30' AND '2015-01-01';
+------------+
| dt |
+------------+
| 2014-11-30 |
| 2014-12-01 |
| 2014-12-02 |
| 2014-12-03 |
| 2014-12-04 |
| 2014-12-05 |
| 2014-12-06 |
| 2014-12-07 |
| 2014-12-08 |
| 2014-12-09 |
| 2014-12-10 |
| 2014-12-11 |
| 2014-12-12 |
| 2014-12-13 |
| 2014-12-14 |
| 2014-12-15 |
| 2014-12-16 |
| 2014-12-17 |
| 2014-12-18 |
| 2014-12-19 |
| 2014-12-20 |
| 2014-12-21 |
| 2014-12-22 |
| 2014-12-23 |
| 2014-12-24 |
| 2014-12-25 |
| 2014-12-26 |
| 2014-12-27 |
| 2014-12-28 |
| 2014-12-29 |
| 2014-12-30 |
| 2014-12-31 |
| 2015-01-01 |
+------------+
SELECT x.dt
, COUNT(*) total
FROM calendar x
JOIN dataset y
ON x.dt BETWEEN y.valid_from AND y.valid_to
GROUP
BY dt;
+------------+-------+
| dt | total |
+------------+-------+
| 2014-12-01 | 3 |
| 2014-12-02 | 2 |
| 2014-12-03 | 2 |
| 2014-12-04 | 2 |
| 2014-12-05 | 2 |
| 2014-12-06 | 1 |
| 2014-12-07 | 1 |
+------------+-------+
所以只是ORDER BY ... LIMIT - 你知道其余的
答案 2 :(得分:0)
SET @d1 = '2014-12-01';
SET @d2 = '2014-12-07';
SELECT x.selected_date, COUNT(*) total
FROM (
select * from
(select adddate('1970-01-01',t4*10000 + t3*1000 + t2*100 + t1*10 + t0) selected_date from
(select 0 t0 union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t0,
(select 0 t1 union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t1,
(select 0 t2 union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t2,
(select 0 t3 union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t3,
(select 0 t4 union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t4) v
where selected_date between @d1 and @d2
) x
JOIN dataset y
ON x.selected_date BETWEEN y.valid_from AND y.valid_to
GROUP
BY selected_date
ORDER
BY total DESC
LIMIT 1;
它基本上是他的解决方案,但不需要额外的日历表。为了获得两个给定日期之间的日期列表,我使用了这个解决方案:https://stackoverflow.com/a/13814885/3342150
由于