MySQL预订可用性,重叠日期范围

时间:2012-08-31 10:35:52

标签: mysql

我有一张预订表:

  • id(int)
  • 数量(tinyint)
  • date_start(timestamp)
  • date_end(timestamp)

预订可以重叠,因此例如可以同时进行20次预订。现在我想做两个查询:

1)检索给定时间段内的最大数量总和

2)在给定时间段内检索最小数量总和

我不知道如何将仅重叠预订的数量加在一起,而不是非重叠预订。任何帮助将不胜感激。

编辑:我为了清晰起见画了一张照片:http://i.imgur.com/8GDLV.png

2 个答案:

答案 0 :(得分:2)

  1. 构建在所需期间内发生的所有预订边界(即开始和结束日期)的列表:

      SELECT date_start AS boundary
      FROM   bookings
      WHERE  date_start BETWEEN @start AND @end
    UNION
      SELECT date_end
      FROM   bookings
      WHERE  date_end BETWEEN @start AND @end
    
  2. 添加到所需时间段之前的边界:

    -- [ from part 1 above ]
    UNION
      SELECT MAX(boundary)
      FROM (
        SELECT MAX(date_start) AS boundary
        FROM   bookings
        WHERE  date_start <= @start
      UNION ALL
        SELECT MAX(date_end)
        FROM   bookings
        WHERE  date_end <= @end
      ) t
    
  3. 在此结果与bookings表之间建立外部联接,保留所有边界,但仅包括预订,如果它有助于之后的同时人数边界:

    FROM bookings RIGHT JOIN (
      -- [ from part 2 above ]
    ) t ON date_start <= boundary AND boundary < date_end
    
  4. 总结每个边界的人数:

    SELECT IFNULL(SUM(quantity),0) AS simultaneous_people
    -- [ from part 3 above ]
    GROUP BY boundary
    
  5. 找出最大值和最小值:

    SELECT MIN(simultaneous_people),
           MAX(simultaneous_people)
    FROM (
      -- [ from part 4 above ]
    ) t
    
  6. 全部放在一起:

    SELECT MIN(simultaneous_people),
           MAX(simultaneous_people)
    FROM (
      SELECT IFNULL(SUM(quantity),0) AS simultaneous_people
      FROM   bookings RIGHT JOIN (
        SELECT date_start AS boundary
        FROM   bookings
        WHERE  date_start BETWEEN @start AND @end
      UNION
        SELECT date_end
        FROM   bookings
        WHERE  date_end BETWEEN @start AND @end
      UNION
        SELECT MAX(boundary)
        FROM (
          SELECT MAX(date_start) AS boundary
          FROM   bookings
          WHERE  date_start <= @start
        UNION ALL
          SELECT MAX(date_end)
          FROM   bookings
          WHERE  date_end <= @end
        ) t
      ) t ON date_start <= boundary AND boundary < date_end
      GROUP BY boundary
    ) t
    

    sqlfiddle上查看。

答案 1 :(得分:1)

在问题的给定数据结构中没有用于分组的字段。因此,假设您按ID进行分组。

1)。要充分利用MAX

SELECT MAX(TotalQty) FROM
(
    SELECT SUM(Quantity) AS TotalQty FROM Bookings
    WHERE date_End<='<To Date>'
    AND date_Start>='<From Date>'
    GROUP BY id
) SumQty

2)。获得最大分钟MIN

SELECT MIN(TotalQty) FROM
(
    SELECT SUM(Quantity) AS TotalQty FROM Bookings
    WHERE date_End<='<To Date>'
    AND date_Start>='<From Date>'
    GROUP BY id
) SumQty

See this SQLFiddle