2012-11-16 3 views
4

비슷한 주제로 몇 가지 질문을했지만이 특정 문제에 대한 해결책을 찾을 수 없으며 입력에 대해 감사 할 것입니다.MySQL/PHP - 사용 가능한 시간 슬롯을 찾으십시오.

사용자가 특정 서비스를 온라인으로 예약 할 수있는 예약 엔진을 작업 중입니다. 특정 날짜 (또는 주) 내에 사용 가능한 시간 슬롯을 찾고 표시하는 데 어려움이 있습니다. 필요한 시간대 (예 : 1 시간)의 길이와 시간대를 예약 할 수있는 영업 시간 (예 : 09 : 00h - 18 : 00h)을 알고 있습니다. 또한 이미 기존 약속을 저장하는 MySQL 테이블이 있습니다. 내 질문에 대한 관련 열은 다음과 같이 :

이제 위에서 언급 한 정보를 제공
id start (datetime)  end (datetime) 
1 '2012-11-16 13:00:00' '2012-11-16 14:30:00' 
2 '2012-11-16 15:00:00' '2012-11-16 16:00:00' 
3 '2012-11-17 12:00:00' '2012-11-16 15:45:00' 
4 '2012-11-17 13:00:00' '2012-11-16 16:15:00' 
... 

, 내가 가능한 시간 슬롯의리스트를 검색하기위한 좋은 (MySQL의 또는 PHP) 솔루션을 찾을 수 없습니다입니다. 조건이 하나 더 있습니다. 시간 슬롯은 분기 단계로만 시작할 수 있습니다. 예. 위의 예제 데이터는 16 시간 동안 1 시간 단위로 표시됩니다.
09:00, 09:15, 09:30, 09:45, 10:00, ..., 12:00, 16:00, 16:15, ..., 17:00.

샘플 데이터에서와 같이 중복되는 시간이있을 수 있지만 사용 가능한 시간대는 겹칠 수 없습니다.

이 접근 방식은 무엇이라고 생각하십니까?

+0

중복 조건은 무엇입니까? 한 명과 함께 서비스 예약을위한 것이거나 한 명 이상의 약속이 동시에 발생할 수 있습니까? – Lucas

+0

1 인 예약입니다. 일반 사용자는 100 % 무료로 사용할 수있는 시간대 만 예약 할 수 있습니다. 겹치지 않는다. 관리자는 오버랩을 허용하는 정교한 캘린더가 다릅니다 (특정 상황에서 오버랩을 처리 할 수 ​​있음을 알고있을 수 있음). 위의 질문에서 유일하게 중요한 점은 시스템이 가용성을 찾으려 고 시도해야하는 데이터베이스 테이블에 겹치는 슬롯이있을 수 있다는 것입니다. – j2dab

답변

6
SELECT a.end AS free_after 
FROM bookings a 
WHERE NOT EXISTS (
    SELECT 1 
    FROM bookings b 
    WHERE b.start BETWEEN a.end AND a.end + INTERVAL your_duration HOURS 
) 
AND a.end BETWEEN start_of_search_window AND end_of_search_window; 

당신은 your_duration (정수), start_of_search_window (날짜 시간)과 end_of_search_window (날짜 시간) 값을 제공해야합니다.

그리고 당신은 종과 경적을 원하는 경우 ....

SELECT free_from, free_until 
FROM (
    SELECT a.end AS free_from, 
    (SELECT MIN(c.start) 
    FROM bookings c 
    WHERE c.start > a.end) as free_until 
    FROM bookings a 
    WHERE NOT EXISTS (
    SELECT 1 
    FROM bookings b 
    WHERE b.start BETWEEN a.end AND a.end + INTERVAL your_duration HOUR 
) 
    AND a.end BETWEEN start_of_search_window AND end_of_search_window 
) 
ORDER BY free_until-free_from 
LIMIT 0,3; 

는 당신에게 창에서 세 개의 짧은 가능한 슬롯 (즉, 가장 가까운 대상 크기)를 제공 할 것입니다.

+1

완벽한, 정말 고마워! 그게 바로 제가 찾고 있던 것입니다! 결과를 모든 사용 가능한 슬롯으로 가져 오는 것이 가능할 것이라고 생각하십니까? 위의 예에서 결과 행은 2012-11-16 16:00:00 - 2012-11-17 12:00:00입니다. 이 대신 다음과 같은 시간대가 포함 된 많은 행을 선호합니다. 2012-11-16 16:00:00 - 2012-11-16 17:00:00 및 2012-11-16 17:00:00 - 2012 -11-16 18:00:00 등등 ... 아니면 PHP를 사용하여 전체 자유 시간을 슬롯으로 나누겠습니까? – j2dab

+1

한 가지 더, 나는 당신의 해결책을 가지고 놀았으며 스스로 해결할 수없는 까다로운 문제를 발견했습니다. 내 성명을 start_of_search_window 2012-11-16 00:00:00 및 end_of_search_window 2012-11-18 00:00:00과 함께 사용하면 2012-11-16 00:00:00과 2012-11-11 사이의 무료 차단이 누락됩니다. 16 13:00:00. 예. 첫 번째 약속이 발견 된 후에 만 ​​free_from으로 시작합니다. 이 버그를 수정하는 방법에 대한 올바른 방향을 가르쳐 주시겠습니까 ..? – j2dab

+0

개념적으로는 사소한 것입니다. '예약 a'테이블을 창 시작시 끝나는 더미 약속이 포함 된 가상 테이블로 대체하십시오. 그러나 SQL은 다소 복잡합니다. – symcbean

관련 문제