2012-03-16 59 views
1

我有一個表availablities持有用戶的可用性:與相鄰的時間戳結合行WHERE子句中

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)(2)的兩行user_id (1)組合起來,因爲只有這兩個可用性的總和適合該事件。

在完美的世界中,行0123¾上的相鄰可用性將只在一行中。有幾個原因可以用這種方式保存,我不能只是「優化」表中的數據,將相鄰的可用性合併到一行中。

所以我需要的是在給定的時間範圍內,在一個查詢中返回user_ids (1,2,3)的方法 - 可能還是我必須找到另一種方法?

+0

我認爲這將變得更加容易了「高級別」你走,而不是試圖編寫一個查詢(這可能是沒有可能至少創建視圖第一)。更高級別的意思是存儲過程或更好的腳本語言。 – 2012-03-16 10:40:53

回答

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'); 
+0

謝謝,這正是我所需要的,即使在超過25,000行的桌子上,它也能完美運行。非常感激你的幫助! – MiDo 2012-03-16 11:48:14