2011-01-10 2 views
2

날짜 범위 (시작일과 종료일)와 요율 필드가 포함 된 테이블이있는 데이터베이스 (MySQL)가 있습니다. 기간은 다른 계절 (낮음, 높음 등)을 의미합니다. 이 시나리오는 한 사람이 호텔을 체크인하고 그의 체류 기간이 두 시즌에있는 것과 같습니다. 샘플 데이터는 다음과 같다 : 날짜에서다른 계절의 객실 요금

SeasonName   SartDate   EndDate   Rate 
Low    01-01-2007   30-04-2007  100.00 
High    01-05-2007   31-08-2007  150.00 
Peak    01-09-2007   31-12-2007  200.00 

클라이언트의 확인이 29-04-2007하고 2007년 3월 5일이다 날짜를 체크 아웃. 계절별로 정확한 밤을 계산하고 총계를 계산해야합니다.

IDE는 VB6입니다. 어떤 도움이라도 대단히 감사하겠습니다. 응답에 대한

감사

감사합니다. 정보를 추출하려면 SQL이 필요합니다. 날짜 유효 기간은 자정 (00:00)까지 적용됩니다. 희망을 분명히했습니다.

+1

무엇이 문제입니까? SQL? 코드를 실행하는 데 사용 되나요? 데이터 파싱? 데이터 렌더링? 더 많은 정보가 필요합니다. –

+2

밤에는 2 일 동안 벌어집니다. 먼저 4 월 30 일에 종료되는 요율이 하루가 끝날 때 밤에 적용되는지, 아니면 같은 날 밤이 1 월부터 적용되는 요율인지 여부를 정의해야합니다. –

답변

0

면책 조항 : 이것은 가장 효율적인 아니다, 그러나 더 분명, 당신은 배열에 캐시 가격 목록이있는 경우, 성능 저하는 의미가 될 것입니다.

Dim numberOfDays As Integer, i As Integer 
Dim CheckInDate As Date, CheckOutDate As Date, CurrDate As Date 
Dim TotalRate As Currency 
TotalRate = 0 
CheckInDate = DateSerial(2007, 4, 29) 
CheckOutDate = DateSerial(2007, 5, 3) 
''// -1 asumming the last day is checkout day 
numberOfDays = DateDiff("d", CheckInDate, CheckOutDate) - 1 
For i = 0 To numberOfDays 
    CurrDate = DateAdd("d", i, CheckInDate) 
    TotalRate = TotalRate + CalculateRateForDay(CurrDate) 
Next 
1

나는 두 날짜 사이의 일 수를 알아 내기 위해 DATEDIFF 함수를 사용했습니다.

SeasonName   StartDate   EndDate   Rate 
Low    01-01-2007   01-05-2007  100.00 
High    01-05-2007   01-09-2007  150.00 
Peak    01-09-2007   01-01-2008  200.00 

이 내가 사용하는 쿼리는 다음과 같습니다이 함수는 마지막 날 (1 대신 2의 예를 들면, DATEDIFF(d, '2007-04-29', '2007-04-30') 창)을 제외한 일수를 반환하기 때문에, 나는이 같은 속도 테이블을 사용했다. 2 개의 SELECT의 내부는 계절 (계절 종료 날짜 또는 체크 아웃 날짜 이전 날짜)에 따라 고객의 체류 유효 종료 날짜를 계산합니다.

보통 고객이 대금을 지불하지 않으므로 03-05-2007 대신 02-05-2007을 고객의 체류 종료 날짜로 사용했습니다.

SELECT SeasonName, DATEDIFF(d, '2007-04-29', EffectiveEndDate) as NumberOfDays, Rate 
FROM (
    SELECT SeasonName, 
    CASE 
    WHEN EndDate < '2007-05-02' THEN EndDate 
    ELSE '2007-05-02' 
    END AS EffectiveEndDate, 
    Rate 
    FROM HotelRate 
    WHERE (StartDate <= '2007-04-29' and EndDate > '2007-04-29') 
    or (StartDate <= '2007-05-02' and EndDate > '2007-05-02') 
) as SubSelect 

이 나에게이 결과 제공 :

SeasonName NumberOfDays Rate 
Low  2    100.00 
High  3    150.00 

내가 도움이 :)

+0

나는 당신의 솔루션이 너무 제한적이라고 생각합니다. 추측이 2 시즌 이상 지속된다면 어떻게 될까요? (대부분의 호텔에는 긴 주말, 공휴일 등 특별 요금이 있습니다.) –

+0

네 말이 맞아, 오래 머물러서는 안된다. 난 detailled 달력 테이블과 네이트 C의 솔루션을 좋아해. –

0

사용 희망을 auxiliary calendar table :

SELECT S1.client_ID, H1.Rate, C1.dt 
    FROM HotelRates AS H1 
     INNER JOIN Calendar AS C1 
      ON C1.dt BETWEEN H1.SartDate AND H1.EndDate 
     INNER JOIN Stays AS S1 
      ON C1.dt >= check_in_date AND 
      C1.dt < check_out_date; 
8

이 호텔에서 근무하고 예약을 만들었고 시스템, 시간당 시간은 무의미합니다. 으로 결제가 진행됩니다. 모든 것은 항상 밤에 청구됩니다. (한시간 씩 요금을 청구하는 장소를 운영하지 않을 경우 !;-)) 체크인 및 체크 아웃은 운영상의 고려 사항입니다.

실제 예약 시스템을 실제로 작성하려면 저장 프로 시저를 사용하지 마십시오. 데이터베이스를 보유하는 목적을 상쇄합니다.

또한 2007-04-29와 같은 날짜는 모두 똑같은 장소에있는 것은 아니기 때문에 2007-04-29 날짜를 작성하는 것이 좋습니다. 이는 국제 표준입니다. 또한이를 문자열로 바꾸려면 여전히 올바르게 정렬됩니다.

MySQL에 내장 된 함수가 없으므로 calandar 테이블을 만들어야합니다. 이 절차는 날짜를 작성합니다. 에서

drop table if exists calendar; 
create table calendar 
( 
    date_  date  primary key 
); 

drop procedure fill_calendar; 

delimiter $$ 
create procedure fill_calendar(start_date date, end_date date) 
begin 
    declare date_ date; 
    set date_=start_date; 
    while date_ < end_date do 
    insert into calendar values(date_); 
    set date_ = adddate(date_, interval 1 day); 
    end while; 
end $$ 
delimiter ; 

call fill_calendar('2007-1-1', '2007-12-31'); 

: http://www.ehow.com/how_7571744_mysql-calendar-tutorial.html

drop table if exists rates; 
create table rates 
(
    season   varchar(100) primary key, 
    start_date  date   references calendar(date_), 
    end_date  date   references calendar(date_), 
    rate   float 
); 
insert into rates values ('Low', '2007-01-01', '2007-04-30', 100.00); 
insert into rates values ('High', '2007-05-01', '2007-08-31', 150.00); 
insert into rates values ('Peak', '2007-09-01', '2007-12-21', 200.00); 

select * from rates; 
season start_date  end_date  rate 
Low  2007-01-01  2007-04-30  100 
High 2007-05-01  2007-08-31  150 
Peak 2007-09-01  2007-12-21  200 

나는 당신이 당신의 질문에 준 날짜를 무시하는거야와 클라이언트가 시간 뒤로 이동하지 않습니다 가정합니다.

select 
    date_, rate 
    from calendar 
    join rates 
     on date_ >= start_date and date_ <= end_date 

    where date_ between '2007-04-29' and '2007-5-01' 
; 
date_ rate 
2007-04-29  100 
2007-04-30  100 
2007-05-01  150 

select 
    sum(rate) 

    from calendar 
    join rates 
     on date_ >= start_date and date_ <= end_date 

    where date_ between '2007-04-29' and '2007-5-01' 
sum(rate) 
350 

그리고 알 수 있듯이 SQL은 기능이나 절차에 의존하지 않고도 매우 간결하고 읽기 쉽습니다. 이것은 적절하게 확장되고 더 복잡한 질문을 처리 할 수 ​​있습니다. 또한 데이터가 테이블 기반이기 때문에 참조 검사를 사용할 수 있습니다.

+0

+1 문제에 대한 좋은 답변 – Tony

관련 문제