检查MySQL中的日期范围

时间:2014-10-16 08:28:51

标签: php mysql

我正在为美容院预订系统。我有桌子:

提供者 - 沙龙的工作人员。

TABLE `providers` (
  `providerId` int(11) NOT NULL AUTO_INCREMENT,
  `providerName` varchar(150) NOT NULL DEFAULT '',
  PRIMARY KEY (`providerId`)
)

101 Anna
102 Beata

服务 - 他们提供的不同服务

TABLE `services` (
  `serviceId` int(11) NOT NULL AUTO_INCREMENT,
  `service` varchar(150) NOT NULL DEFAULT '',
  `serviceDuration` int(11) NOT NULL,
  `providerId` int(11) NOT NULL,
  PRIMARY KEY (`serviceId`)
)

1   Hair cut    30  101
2   Hair coloring   120 101

时间表 - 每个提供商提供不同服务时的表格

TABLE `schedule` (
  `scheduleId` int(11) NOT NULL AUTO_INCREMENT,
  `serviceId` int(11) NOT NULL,
  `providerId` int(11) NOT NULL,
  `scheduleStartDateTime` datetime NOT NULL,
  `scheduleEndDateTime` datetime NOT NULL,
  PRIMARY KEY (`scheduleId`)
)

1   1   101 2014-10-17 10:00:00 2014-10-17 10:29:59
2   1   101 2014-10-17 10:30:00 2014-10-17 10:59:59
3   1   101 2014-10-17 11:00:00 2014-10-17 11:29:59
4   1   101 2014-10-17 11:30:00 2014-10-17 11:59:59
5   1   101 2014-10-17 12:00:00 2014-10-17 12:29:59
6   2   101 2014-10-17 10:30:00 2014-10-17 12:29:59

最后,预订 - 预订服务的表格。

TABLE `bookings` (
  `bookingId` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `clientId` int(11) NOT NULL,
  `bookingDate` datetime NOT NULL,
  `serviceId` int(11) NOT NULL,
  `providerId` int(11) DEFAULT NULL,
  `startDateTime` datetime NOT NULL,
  `endDateTime` datetime NOT NULL,
  PRIMARY KEY (`bookingId`)
)

1   1   2014-10-16  1   101 2014-10-17 10:30:00 2014-10-17 10:59:59

当然有更多的客户,付款等表格已加入 进入搜索。

我的问题是搜索每个提供商找到未预订的可用服务。

假设有人想要安娜剪头发。然后,我想提供可用的剪发时间,不包括已经预订的10:30:00。

select s.serviceId, s.providerId, s.scheduleStartDateTime, s.scheduleEndDateTime
FROM schedule AS s
WHERE s.serviceId = '1'
AND s.providerId NOT IN
(
    SELECT providerId
    FROM bookings
    WHERE startDateTime <= s.scheduleEndDateTime 
    AND endDateTime >= s.scheduleStartDateTime
)

但是这个搜索给出了这个结果:

1   101 2014-10-17 10:00:00 2014-10-17 10:29:59
1   101 2014-10-17 10:30:00 2014-10-17 10:59:59  <-- This should not show up
1   101 2014-10-17 11:00:00 2014-10-17 11:29:59
1   101 2014-10-17 11:30:00 2014-10-17 11:59:59
1   101 2014-10-17 12:00:00 2014-10-17 12:29:59

http://sqlfiddle.com/#!2/9e5f22

3 个答案:

答案 0 :(得分:0)

我认为你的SQL应该是这样的:

select s.serviceId, s.providerId, s.scheduleStartDateTime, s.scheduleEndDateTime
FROM schedule AS s
WHERE s.serviceId = '1'
AND s.providerId NOT IN
(
    SELECT b.providerId
    FROM bookings AS b
    WHERE b.startDateTime >= s.scheduleEndDateTime 
    AND b.endDateTime <= s.scheduleStartDateTime
)

子查询应该选择已预订的子查询,因此主查询将排除这些预订。

答案 1 :(得分:0)

日程表对我来说似乎很奇怪。您是否计划在每天的计划表中预先生成行?如果是这样,那么预订表只需要存储预订时段的计划ID,但由于服务的长度不同,所以它变得更加困难。

似乎可以简化计划概念。您需要知道每个提供商的开始和停止时间。然后,您可以在特定的开始时间安排服务,持续时间长度(30分钟或120分钟)。开始时间和持续时间阻碍了提供者的日程安排。

当客户想要创建预订时,他们可以选择具有足够长持续时间的可用开始时间(每30分钟)(即提供者计划中的空缺)。搜索查询可以检索现有预订,然后您可以在显示方面限制客户的选择。

答案 2 :(得分:0)

我在sqlfiddle中得到了正确答案(更改了我在预订表中输入的错误日期后)。 我在原始表中遇到了同样的错误。问题解决了!