计算多个范围内给定日期之间的价格

时间:2013-04-30 18:15:12

标签: mysql sum date-range

以下代码在两个或更多范围内使用时效果很好,但在开始日期和结束日期在同一范围内时则不行。当开始日期和结束日期在相同范围内时,totalprice将返回额外的一天。因此,一晚的总价格翻了一倍。

这是mysql表;

CREATE TABLE rooms (
 Hotel_id INT,
 Room_id INT,
 Room_type VARCHAR(20),
 Start_date DATE,
 End_date DATE,
 Price INT
);

INSERT INTO rooms VALUES
(   13   ,     2     ,   'standard' ,  '2012-08-01' ,  '2012-08-15'  , 7000),
(   13   ,     2     ,   'standard' ,  '2012-08-16' ,  '2012-08-31'  , 7500),
(   13   ,     2     ,   'standard' ,  '2012-09-01' ,  '2012-09-30'  , 6000),
(   13   ,     3     ,    'luxury'  ,  '2012-08-01' ,  '2012-08-15'  , 9000),
(   13   ,     3     ,    'luxury'  ,  '2012-08-16' ,  '2012-08-31'  , 10000),
(   13   ,     3     ,    'luxury'  ,  '2012-09-01' ,  '2012-09-30'  , 9500),
(   13   ,     3     ,    'luxury'  ,  '2012-10-01' ,  '2012-10-15'  , 15000);

这是代码;

SELECT     SUM(
           CASE WHEN a.Start_date = b.min_sd AND a.Start_date <> b.max_sd THEN
                    (DATEDIFF(a.End_date, '2012-09-03')+1) * a.Price
                WHEN a.Start_date = b.max_sd AND a.Start_date <> b.min_sd THEN
                    DATEDIFF('2012-09-04', a.Start_date) * a.Price
                WHEN (a.Start_date,a.Start_date) IN ((b.min_sd,b.max_sd)) THEN
                    (DATEDIFF('2012-09-04', '2012-09-03')+1) * a.Price
                WHEN a.Start_date NOT IN (b.min_sd, b.max_sd)             THEN
                    (DATEDIFF(a.End_date, a.Start_date)+1) * a.Price
           END 
       ) AS totalprice
FROM       rooms a
CROSS JOIN (
       SELECT MIN(Start_date) AS min_sd,
              MAX(Start_date) AS max_sd
       FROM   rooms
       WHERE  Room_type   = 'luxury'     AND
              End_date   >= '2012-09-03' AND
              Start_date <= '2012-09-04'
       ) b
WHERE      a.Room_type   = 'luxury'     AND
       a.End_date   >= '2012-09-03' AND
       a.Start_date <= '2012-09-04';

1 个答案:

答案 0 :(得分:3)

你可以使用这样的查询:

SELECT
  SUM(
    DateDiff(
      Least(End_Date + INTERVAL 1 DAY, '2012-09-04'),
      Greatest(Start_Date, '2012-08-31')
    ) * Price
  )
FROM
  rooms a
WHERE
  a.Room_type   = 'luxury'     AND
  a.End_date   >= '2012-08-31' AND
  a.Start_date <  '2012-09-04';

请参阅小提琴here