(my)SQL only 解决方案,用于显示议程系统中的可用时间段

Posted

技术标签:

【中文标题】(my)SQL only 解决方案,用于显示议程系统中的可用时间段【英文标题】:(my)SQL only solution to show available time slots from agenda system 【发布时间】:2013-02-09 16:52:22 【问题描述】:

说明 我正在制作一个带有(多个)议程的议程系统,您可以在选定的时间段内(例如上午 9:00 到上午 11:00)保留可变时间(10/15/20 或 30 分钟)的时间段周一和上午 10:30 至下午 3:00)

当然,我可以在 php 中执行此操作,并轮询约会和可用性表,了解每个显示的每个日期可用的时间段,但有些听起来有点服务器密集型。所以我想知道是否有一种方法可以生成一个显示时隙和可用性元组的 mysql 结果关系......

数据库/表设置 这是我认为必要的表格设置。

约会 holds the appointments already made 编号 |整数unique id 议程ID |整数unique id identifying the agenda 开始 |日期时间start of the appointment 结束 | date_time end of the appointment更多描述性字段

可用性 when are there which time slots available 议程ID |整数identifying which agenda day_of_the_week |整数which day, eg 1=monday 开始时间 |时间e.g. 09:00:00 结束时间 |时间e.g. 11:00:00 时隙 |整数how long are the time slots? e.g. 10minutes

(备注: 如果需要,也可以对 time_slots 字段进行硬编码; 系统运行在 MySQL 数据库上,如果需要我们可以切换到 postgresql )

想要的结果 给定一个日期 2013-02-21 和一个议程 ID 1(如果需要,还有时间段 15)和一个从 8:00 到 18:00 的工作日; 如何创建 mysql 查询、视图或存储过程以生成以下表/关系:

date       | 8:00 | 8:15 | 8:30 | 8:45 | 9:00 | 9:15 | ..... | 17:15 | 17:30 | 17:45 |
2013-02-21 |   0  |  0   |   0  |  0   |  1   |   2  | ..... |   2   |   2   |   1   |

地点: 0 = 不可预订 1 = 可用,您可以预订此时段 2 = 不可用,有约会

【问题讨论】:

【参考方案1】:

如果您决定切换到 PostgreSQL,您可能需要确保您使用的是 9.2 版(或更高版本),以便您可以充分利用 range types 和 exclusion constraints。 GiST 索引对此类数据非常有用,但排除约束会自动创建一个,因此您可能不需要显式声明一个。如果您想列出一定范围内的可用空缺时间,可以使用generate_series 函数将候选时间与现有时间表与NOT x && y 结合起来,以过滤掉不可用的时间。

我不确定 MySQL 中的等价物是什么。

【讨论】:

【参考方案2】:

您希望调整约会并与可用性进行比较。这是一个带有条件聚合的连接和聚合查询。思路如下:

select agendaId, const.thedate,
       sum(case when thedate + interval 8 hour + interval 0 minute between ap.start and ap.end
                then 1 else 0
           end) as "8:00",
       sum(case when thedate + interval 8 hour + interval 15 minute between ap.start and ap.end
                then 1 else 0
           end) as "8:15",
       . . .
from (select date('2013-02-21' ) as thedate) const cross join
     Availability a left outer join
     Appointments ap
     on a.AgendaId = ap.AgendaId and
        const.day_of_the_week = weekday(const.thedate)        
where date(ap.start) = const.thedate 
group by AgendaId

【讨论】:

以上是关于(my)SQL only 解决方案,用于显示议程系统中的可用时间段的主要内容,如果未能解决你的问题,请参考以下文章

GROUP BY不适用于MySQL 5.7,因为5.7使用SQL_MODE的“ONLY_FULL_GROUP_BY”选项。

mysql 使用 GROUP BY 时报错 ERROR 1055 (42000)

this is incompatible with sql_mode=only_full_group_by错误解决

如何在 Emacs 启动时显示 Org 模式议程?

mysql-5.7.22'this is incompatible with sql_mode=only_full_group_by'解决方法

MySQL-[Err] 1055 - Expression #1