繁体   English   中英

MySQL预留系统 - 测试多种条件

[英]MySQL Reservation System - Testing for multiple conditions

我正在研究MySQL中的预订系统,我在查询下一个可用的预约空档时遇到了一些麻烦。

我的日子分为15分钟(00:00:00 - 00:14:59,00:15:00-00:29:59等)。 表结构到目前为止:

约会表:

CREATE TABLE IF NOT EXISTS `appointments` (
`appointmentID` int(9) unsigned NOT NULL AUTO_INCREMENT,
`patientID` int(9) unsigned NOT NULL,
`apptTitle` varchar(50) NOT NULL,
`apptDT` datetime NOT NULL,
`apptLength` int(4) NOT NULL,
`apptStatus` varchar(25) NOT NULL,
`physician` int(9) unsigned NOT NULL,
`apptType` varchar(30) NOT NULL,
`apptLocation` varchar(25) NOT NULL,
PRIMARY KEY (`appointmentID`),
KEY `patientID` (`patientID`),
KEY `physician` (`physician`),
KEY `apptStatus` (`apptStatus`),
KEY `apptLocation` (`apptLocation`),
KEY `apptType` (`apptType`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=4 ;

apptSlots表:

CREATE TABLE IF NOT EXISTS `apptSlots` (
`startDT` datetime NOT NULL,
`endDT` datetime NOT NULL,
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;

正如我在上面解释的那样,apptSlots表已经填满了2012年的所有15分钟时段。

我有一个查询,可以成功地向我显示没有采取任何方式的插槽(根本没有安排预约)。

SELECT a.*
FROM apptSlots AS a
LEFT JOIN appointments AS b
ON a.endDT
BETWEEN b.apptDT AND DATE_ADD(b.apptDT, INTERVAL b.apptLength MINUTE)
AND b.appointmentID IS NULL

我现在需要做的是搜索多个医生,多个房间等的预约位置。例如,如果医生A预约上午7点 - 早上8点,那个时间段不再出现在我的查询中。 但是医生B和C没有任何关于那个插槽的约会,所以我需要能够安排它们。 房间也是如此,房间A在早上7点预约时使用,但B和C房仍可免费预定。

如何确定所有这些变量的开放槽? 我知道我可以测试每个组合的WHERE条件,如果我需要测试特定的医生或特定的治疗室,这是有效的。 但是,如果我只想查看所有医生和房间的所有插槽,我的查询不起作用并单独测试所有可能的组合似乎不对,这只是如何在LEFT JOIN子句中获得正确条件的问题。

如果我不清楚,请告诉我,但我认为这是足够的信息。 如果没有,我会添加你要求的任何东西!

谢谢你的帮助,我在这里的上一个问题让我得到了上面的查询,现在我只需要一些改进。 问你需要的任何问题,我会在这里回答他们!

根据要求,这是我的各种评论中的答案:

请注意,您不能只有一个表用于约会时段。 每位医生都会有不同的时间表,包括假期等.soctor_id应该是available_appointments表的一部分。

您还有“资源”,如预约室或便携式设备等。这些应该位于不同的表(available_resources?)中,具有自己的可用性和日程安排。

至于找时间块,试试这个:

set @last_time = null;
set @block_size = 1;

select *
from (
  select startDT,
    case when @last_time is null or startDT = date_add(@last_time, interval 15 minute)
      then @block_size := @block_size + 1
      else @block_size := 1
    end as block_size,
    @last_time := startDT
  from foo_appt
) foo
where block_size = 4;

编辑:

这是我的测试数据:

+---------------------+
| startDT             |
+---------------------+
| 2012-11-06 13:00:00 |
| 2012-11-06 13:15:00 |
| 2012-11-06 14:00:00 |
| 2012-11-06 14:15:00 |
| 2012-11-06 14:30:00 |
| 2012-11-06 14:45:00 |
| 2012-11-06 16:00:00 |
| 2012-11-06 16:15:00 |
+---------------------+

所以有一个30分钟的街区,然后是一个小时的街区,然后是另一个30分钟的街区。

内部查询执行繁重的工作并生成以下输出。 最后两列只是为了维护这两个变量,应该被忽略。

+---------------------+------------+-------------+-----------------------+
| startDT             | block_size | @block_size | @last_time := startDT |
+---------------------+------------+-------------+-----------------------+
| 2012-11-06 13:00:00 |          1 |           1 | 2012-11-06 13:00:00   |
| 2012-11-06 13:15:00 |          2 |           2 | 2012-11-06 13:15:00   |
| 2012-11-06 14:00:00 |          1 |           1 | 2012-11-06 14:00:00   |
| 2012-11-06 14:15:00 |          2 |           2 | 2012-11-06 14:15:00   |
| 2012-11-06 14:30:00 |          3 |           3 | 2012-11-06 14:30:00   |
| 2012-11-06 14:45:00 |          4 |           4 | 2012-11-06 14:45:00   |
| 2012-11-06 16:00:00 |          1 |           1 | 2012-11-06 16:00:00   |
| 2012-11-06 16:15:00 |          2 |           2 | 2012-11-06 16:15:00   |
+---------------------+------------+-------------+-----------------------+

外部查询允许您只获取具有相应block_size的那些。 你得到了第4个街区的开始时间

MySQL不允许您在查询中一次设置多个变量(您必须在程序中执行此操作),这在尝试像这样混乱时会令人失望。

想到的最容易的事情是采取第4个时期并减去第一个时期的开始,所以外部查询将如下所示:

select date_sub(startDT, interval 15 * (block_size-1) minute) as appointment_time,
    block_size*15 as appointment_duration
from ( ...

+---------------------+----------------------+
| appointment_time    | appointment_duration |
+---------------------+----------------------+
| 2012-11-06 14:00:00 |                   60 |
+---------------------+----------------------+

希望有所帮助。

尝试这个。 我相信这应该可以解决问题,假设你有一个医生表。

SELECT  a.* 

FROM    apptSlots AS a 

        CROSS JOIN employees p 

        LEFT JOIN appointments AS b 
        ON p.employeeID = b.physician 
        AND a.endDT BETWEEN b.apptDT AND DATE_ADD(b.apptDT, INTERVAL b.apptLength MINUTE)

WHERE   b.appointmentID IS NULL

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM