【问题标题】:MySQL Availability CalendarMySQL 可用性日历
【发布时间】:2013-04-24 14:45:41
【问题描述】:

我有一个预订系统,我想显示列表的每月日历视图。我有以下表结构(还有很多其他列);

CREATE TABLE `sys_calendar` (
    `dt` date NOT NULL,
    PRIMARY KEY (`dt`)
);

CREATE TABLE `listings` (
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
    `title` varchar(255) NOT NULL,
    PRIMARY KEY (`id`),
);

CREATE TABLE `bookings` (
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
    `listing_id` int(10) unsigned NOT NULL,
    `start_date` date NOT NULL,
    `end_date` date NOT NULL,
    PRIMARY KEY (`id`)
);

sys_calendar 保存从 2000-01-012040-12-31 的所有日期;

dt
------------
2000-01-01
2000-01-02
2000-01-03
....
2040-12-30
2040-12-31

我想要做的是显示特定列表的月历。例如;我想在 2013 年 4 月显示 listing_id = 10 的日历(bookings 表上的 2013-04-01 和 2013-04-30 之间)。

dt         | Availability
-------------------------
2013-04-01 | No
2013-04-02 | No
2013-04-03 | Yes
2013-04-04 | Yes
2013-04-05 | Yes
2013-04-06 | Yes
....
2013-04-29 | No
2013-04-30 | Yes

我知道我必须加入 sys_calendarbookings 表,但不知道如何。

【问题讨论】:

    标签: mysql sql calendar


    【解决方案1】:

    我认为这对你有用:

    SELECT  c.dt,
            CASE WHEN COUNT(b.id) > 0 THEN 'No' ELSE 'Yes' END AS Availability
    FROM    sys_calendar c
            LEFT JOIN bookings b
                ON b.Listing_id = 10
                AND c.dt BETWEEN b.Start_Date AND b.End_Date
    GROUP BY c.dt;
    

    Example on SQL Fiddle

    此外,如果您想显示可以使用的多个可用性:

    SELECT  c.dt,
            CASE WHEN COUNT(CASE WHEN b.Listing_id = 1 THEN 1 END) > 0 THEN 'No' ELSE 'Yes' END AS Availability1,
            CASE WHEN COUNT(CASE WHEN b.Listing_id = 2 THEN 1 END) > 0 THEN 'No' ELSE 'Yes' END AS Availability2,
            CASE WHEN COUNT(CASE WHEN b.Listing_id = 3 THEN 1 END) > 0 THEN 'No' ELSE 'Yes' END AS Availability3,
            CASE WHEN COUNT(CASE WHEN b.Listing_id = 4 THEN 1 END) > 0 THEN 'No' ELSE 'Yes' END AS Availability4
    FROM    sys_calendar c
            LEFT JOIN bookings b
                ON c.dt BETWEEN b.Start_Date AND b.End_Date
    WHERE   c.dt BETWEEN '20130401' AND '20130430'
    GROUP BY c.dt;
    

    Example on SQL Fiddle

    【讨论】:

    • 谢谢 GarethD。这两个查询都很好,但是有一个影响整个系统的小问题。根据您的回答,我将第一个查询改写为SELECT c.dt, CASE WHEN COUNT(b.id) > 0 THEN 'No' ELSE 'Yes' END AS Availability FROM sys_calendar c LEFT JOIN bookings b ON b.listing_id = 16 AND c.dt >= b.start_date AND c.dt < b.end_date WHERE c.dt BETWEEN '20130401' AND '20130430' GROUP BY c.dt;。预订的最后一天必须标记为可用,因为客人在中午 12 点之前离开房间,所以下午房间又可以使用了。我想我忘了告诉这个。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-08
    • 1970-01-01
    • 1970-01-01
    • 2012-05-18
    • 1970-01-01
    相关资源
    最近更新 更多