我有一个表availablities
,其中包含用户的可用性:
row_id | user_id | available_from | available_to
-------------------------------------------------------------
1 | 1 | 2012-02-01 08:00:00 | 2012-02-01 09:00:00
2 | 1 | 2012-02-01 09:00:00 | 2012-02-01 10:00:00
3 | 2 | 2012-02-01 08:00:00 | 2012-02-01 10:00:00
4 | 3 | 2012-02-01 07:00:00 | 2012-02-01 12:00:00
我需要从此表中获取特定事件的所有可用用户。
场景:获取以2012-02-01 08:00:00
开头并结束2012-02-01 10:00:00
的活动的所有可用用户。
获取user_ids (2,3)
时没问题:
SELECT `user_id` FROM `availablities`
WHERE `available_from` <= "2012-02-01 08:00:00"
AND `available_to` >= "2012-02-01 10:00:00"
我很难找到一个也会返回user_id (1)
的查询。为此,查询必须显示组合(1)
的{{1}}和(2)
两行,因为只有这两个可用性的总和符合事件。
在完美的世界中,行user_id (1)
上的相邻可用性将只在一行中。有理由以这种方式保存它,我不能只是“优化”表格中的数据来组合一行中的相邻可用性。
所以我需要的是mysql在给定时间范围内在一个查询中返回(1,2)
的方法 - 可能还是我必须找到另一种方法?
答案 0 :(得分:1)
如果您需要在一个查询中执行此操作,您可以尝试组合MySQL用户定义变量和一些内联视图技巧:
select d.*
from
(
select u.user_id,u.consec as available_from,max(u.available_to) as available_to
from
(
select a.*,
case when @lastEndDate != a.available_from then @curStartDate := a.available_from else @curStartDate end as consec,
@lastEndDate := a.available_to as c
from availabilities a
inner join (select @curStartDate := null,@lastEndDate := "1970-01-01 00:00:00") as t
order by a.user_id,a.available_from
) u
group by u.user_id,u.consec
) d
where d.available_from <= "2012-02-01 08:00:00"
AND d.available_to >= "2012-02-01 10:00:00";
我拿了你的测试数据并包括一个用户(user_id = 4),他在2012-02-01 08:00:00和2012-02-01 08:30:00之间可用,然后再在2012年之间-02-01 09:00:00和2012-02-01 10:00:00所以他在2012-02-01 08:00:00和2012-02-01 10:00:00(喝咖啡休息时间?!)之间的整段时间都没空。
因此预期的结果是在该时间段内返回user_id = 1但是user_id = 4不是。
以下是我使用的测试:
drop table if exists availabilities;
create table availabilities
(row_id integer unsigned not null primary key,
user_id integer not null,
available_from datetime not null,
available_to datetime not null
);
insert into availabilities values (1,1,'2012-02-01 08:00:00','2012-02-01 09:00:00');
insert into availabilities values (2,1,'2012-02-01 09:00:00','2012-02-01 10:00:00');
insert into availabilities values (3,2,'2012-02-01 08:00:00','2012-02-01 10:00:00');
insert into availabilities values (4,3,'2012-02-01 07:00:00','2012-02-01 12:00:00');
insert into availabilities values (5,4,'2012-02-01 08:00:00','2012-02-01 08:30:00');
insert into availabilities values (6,4,'2012-02-01 09:00:00','2012-02-01 10:00:00');