2

我们正在开发一个需要支持拆分约会的预订系统。这些约会有上半场,休息期间可以预订其他东西,然后是下半场。

该系统还支持具有标准开始和结束的正常预订。

我们需要检查数据库以查看是否存在与我们希望进行的预订重叠的任何现有预订。

我们以前在 PHP 中做过,但在这种情况下只需要在 mysql 中做。

预订表有:

startDate(总是) splitStartDate(有时) splitEndDate(有时) endDate(总是)

当 splitStartDate 和 splitEndDate 未用于预订时,它们的值为 0000-00-00 00:00:00

我们开始尝试用 ifs 构建 mysql 语句,但它看起来长得离谱。

    "SELECT *
     FROM bookings WHERE
    (
        (
            IF(
                splitStartDate != "0000 00:00:00",
                IF(
                    ((CONVERT_TZ('" . $requested_start_time->format("Y-m-d G:i:s") . "', \"$tzone\", \"UTC\") >= startDate) AND (CONVERT_TZ('" . $requested_start_time->format("Y-m-d G:i:s") . "', \"$tzone\", \"UTC\") < splitStartDate))
                    OR
                    ((CONVERT_TZ('" . $requested_start_time->format("Y-m-d G:i:s") . "', \"$tzone\", \"UTC\") >= splitEndDate) AND (CONVERT_TZ('" . $requested_start_time->format("Y-m-d G:i:s") . "', \"$tzone\", \"UTC\") < endDate))
                    , 1, 0
                ),
                IF(
                    (CONVERT_TZ('" . $requested_start_time->format("Y-m-d G:i:s") . "', \"$tzone\", \"UTC\") < endDate) AND (CONVERT_TZ('" . $requested_start_time->format("Y-m-d G:i:s") . "', \"$tzone\", \"UTC\") >= startDate), 1, 0        
                )
            ) = 1
        )
        OR
        (
            IF(
                splitStartDate != "0000-00-00 00:00:00",
                IF(
                    ((CONVERT_TZ('" . $requested_end_time->format("Y-m-d G:i:s") . "', \"$tzone\", \"UTC\") > startDate) AND (CONVERT_TZ('" . $requested_end_time->format("Y-m-d G:i:s") . "', \"$tzone\", \"UTC\") <= splitStartDate))
                    OR
                    ((CONVERT_TZ('" . $requested_end_time->format("Y-m-d G:i:s") . "', \"$tzone\", \"UTC\") > splitEndDate) AND (CONVERT_TZ('" . $requested_end_time->format("Y-m-d G:i:s") . "', \"$tzone\", \"UTC\") <= endDate))
                    , 1, 0
                ),
                IF(
                    (CONVERT_TZ('" . $requested_end_time->format("Y-m-d G:i:s") . "', \"$tzone\", \"UTC\") > startDate) AND (CONVERT_TZ('" . $requested_end_time->format("Y-m-d G:i:s") . "', \"$tzone\", \"UTC\") <= endDate), 1, 0        
                )
            ) = 1           
        )
        OR 
        (

我们知道必须有一种更简单的方法来做到这一点,但对于它是什么感到困惑。我们会喜欢任何有关如何为此构建 mysql 查询的建议。

在检查可用性时,我们一直在运行以下检查(对不起,这需要多长时间,但这就是问题所在):

------------
all simple

requested startDate is in-between existing startDate and existing endDate
requested endDate is in-between existing startDate and existing endDate
existing startDate is in-between requested startDate and requested endDate
existing endDate is in-between requested startDate and requested endDate



-------------
advanced desired / simple existing

requested startDate is in-between existing startDate and existing endDate
requested splitStartDate is in-between existing startDate and existing endDate
existing startDate is in-between requested startDate and requested splitStartDate
existing endDate is in-between requested startDate and requested splitStartDate

requested splitEndDate is in-between existing startDate and existing endDate
requested endDate is in-between existing startDate and existing endDate
existing startDate is in-between requested splitEndDate and requested endDate
existing endDate is in-between requested splitEndDate and requested endDate


------
simple desired / advanced existing

requested startDate is in-between existing startDate and existing splitstartDate
requested endDate is in-between existing startDate and existing splitstartDate
existing startDate is in-between requested startDate and requested endDate
existing splitstartDate is in-between requested startDate and requested endDate

requested startDate is in-between existing splitEndDate and existing endDate
requested endDate is in-between existing splitEndDate and existing endDate
existing splitEndDate is in-between requested startDate and requested endDate
existing endDate is in-between requested startDate and requested endDate

-----
advanced both

1st 1/2 both
requested startDate is in-between existing startDate and existing splitstartDate
requested splitStartDate  is in-between existing startDate and existing splitstartDate
existing startDate is in-between requested startDate and requested splitStartDate
existing splitstartDate  is in-between requested startDate and requested splitStartDate

2/2 desired  1/2 existing
requested splitEndDate  is in-between existing startDate and existing splitstartDate
requested endDate is in-between existing startDate and existing splitstartDate
existing startDate is in-between requested splitEndDate and requested endDate
existing splitstartDate is in-between requested splitEndDate and requested endDate

1/2 desired 2/2 existing
requested startDate is in-between existing splitEndDate and existing endDate
requested splitStartDate  is in-between existing splitEndDate and existing endDate
existing splitEndDate  is in-between requested startDate and requested splitStartDate
existing endDate is in-between requested startDate and requested splitStartDate

2nd 1/2 all
requested splitEndDate is in-between existing splitEndDate and existing endDate
requested endDate is in-between existing splitEndDate and existing endDate
existing splitEndDate is in-between requested splitEndDate and requested endDate
existing endDate is in-between requested splitEndDate and requested endDate

非常感谢

4

1 回答 1

2

我的猜测是,如果你清理你正在做的日期操作的东西,你会喜欢你的查询。

将其移至 mysql 变量:

SET @REQUEST = (CONVERT_TZ('" . $requested_start_time->format("Y-m-d G:i:s") . "', \"$tzone\", \"UTC\");

然后您的代码如下所示:

        IF(
            splitStartDate != "0000 00:00:00",
            IF(
                (@REQUEST >= startDate AND @REQUEST < splitStartDate)
                OR
                (@REQUEST >= splitEndDate) AND @REQUEST < endDate))
                , 1, 0
            ),
            IF(
                (@REQUEST < endDate AND @REQUEST >= startDate), 1, 0        
            )
        ) = 1

这不是不合理的。使用“X = 1”对我来说就像一个 where 子句,所以我更愿意看到

select count(*)
from bookings
where
(
    splitStartDate is not null
        and (
             (@REQUEST >= startDate AND @REQUEST < splitStartDate)
             OR
             (@REQUEST >= splitEndDate) AND @REQUEST < endDate))
        )
)
OR
(
    splitStartDate is null
        and (
            @REQUEST < endDate AND @REQUEST >= startDate
        )
)

祝你好运!

于 2011-04-22T16:39:14.193 回答