开发者

Hotel Booking Rates SQL Problem

Hi I've been trying to get my own system for checking rooms rates going after reading other questions here on StackOverfl开发者_运维知识库ow.

My query works fine and produces correct number of days when there is no overlap of rates in the reservation dates but when is an overlap i get an extra day on my second row of results.

For example a person arrives on the 2011-04-14 and leaves 2011-04-16 (2 Days). There is a rate change from 66 to 70 on the 15th so he should have 1 day at the 66 rate and 1 day at the 70 rate.

I have tried without TIMEDATE - just DATE but same thing happens.

Query

    SELECT rates.rate_id, rate_start_date, rate_end_date, rate_price, 
(DATEDIFF( IF (rate_end_date > '2011-04-16 14:00:00' , '2011-04-16 14:00:00', rate_end_date),
IF ( rate_start_date < '2011-04-14 12:00:00' , '2011-04-14 12:00:00' , rate_start_date )) +1 ) 
AS days FROM rates 
WHERE rate_start_date <= '2011-04-16 14:00:00' AND rate_end_date > '2011-04-14 12:00:00' 
ORDER BY rate_price ASC

rates table

rate_id rate     rate_start_date        rate_end_date
1       70      2011-04-15 00:00:00   2011-05-31 23:59:59
2       80      2011-06-01 00:00:00   2011-06-30 23:59:59
3      100      2011-07-01 00:00:00   2011-08-31 23:59:59
4       80      2011-09-01 00:00:00   2011-09-30 23:59:59
5       70      2011-10-01 00:00:00   2011-10-31 23:59:59
6       45      2011-11-01 00:00:00   2011-12-31 23:59:59
0       66      2011-01-01 00:00:00   2011-04-14 23:59:59

result

rate_id  rate_start_date         rate_end_date       rate    days
0       2011-01-01 00:00:00    2011-04-14 23:59:59  66  1
1       2011-04-15 00:00:00    2011-05-31 23:59:59  70  2 <----this should be 1 day

I would really appreciate any help or an explaination of why my query gives me the extra day of the second row of results.

Thanks


Between 2011-04-16 16:00 and 2011-04-15 00:00 there is one day and 16 hours, therefore your DATEDIFF(...)+1 is returning (correctly) 1+1 days.

The issue here is the mismatch between the time when the guest arrives/leaves (around noon) and the time when the rate changes (at midnight).

You have to check your requirements, but probably you could ignore the last partial day and have the guest "leave" at 2011-04-15 23:59:59 for rate calculation purposes. In the same way, have the guest "arrive" at 2011-04-14 00:00:00. The extra hours in the first day will compensate the missing hours in the last day.


If I understand your algorithm correctly, you want to include first day even partially, so I would suggest you to use instead of + 1 for each rate do this only for the first one.

Try to use this (MSSQL):

+ CASE WHEN rate_start_date <= '2011-04-14 12:00:00' THEN 1 ELSE 0 end

or (MYSQL):

+ IF (rate_start_date <= '2011-04-14 12:00:00', 1 ,0)


Thanks for your answers, Martin your produced 2 rows but no days...Emilio your answer got me thinking about how I had set up the rates. I changed the rate table to date format instead of datetime and made the rate_end_date the same day as the next rate_start_date.

0   66  2011-01-01  2011-04-15
1   70  2011-04-15  2011-06-01
2   80  2011-06-01  2011-07-01
3   100 2011-07-01  2011-09-01
4   80  2011-09-01  2011-10-01
5   70  2011-10-01  2011-11-01
6   45  2011-11-01  2012-01-01

then dropped the +1 and

SELECT rates.rate_id, rate_start_date, rate_end_date, rate_price, 
(DATEDIFF( IF (rate_end_date > '2011-04-16' , '2011-04-16', rate_end_date), 
IF ( rate_start_date < '2011-04-14' , '2011-04-14' , rate_start_date )) ) 
AS days FROM rates WHERE rate_start_date <= '2011-04-16' 
AND rate_end_date > '2011-04-14' 
ORDER BY rate_price ASC

produced

rate_id   rate_start_date   rate_end_date   rate  days    
    0   2011-01-01  2011-04-15  66  1
    1   2011-04-15  2011-06-01  70  1

and a query with no overlapping rates from the 1st to the 8th of April:

SELECT rates.rate_id, rate_start_date, rate_end_date, rate_price, 
(DATEDIFF( IF (rate_end_date > '2011-04-08' , '2011-04-08', rate_end_date), 
IF ( rate_start_date < '2011-04-01' , '2011-04-01' , rate_start_date )) ) 
AS days FROM rates WHERE rate_start_date <= '2011-04-08' 
AND rate_end_date > '2011-04-01' 
ORDER BY rate_price ASC

produces:

rate_id   rate_start_date    rate_end_date   rate  days
    0     2011-01-01       2011-04-15     66    7

thanks agiain for your help!

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜