给出下表:
资源
| id | name |
| 1 | John |
| 2 | Anna |
预订
| id | start | end | resource_id |
| 1 | 2020-05-29 08:00:00 |2020-05-29 12:00:00 | 1 |
我要查找n个日期段的所有可用资源。我可以使用子查询构建动态查询,如下所示:
SELECT name, (
SELECT COUNT(id) FROM bookings WHERE
resources.id = bookings.resource_id
AND '2020-05-29 08:00:00' < `end`
AND '2020-05-29 09:00:00' > `start`
) AS 'dp1',
(SELECT COUNT(id) FROM bookings WHERE
resources.id = bookings.resource_id
AND '2020-05-29 09:00:00' < `end`
AND '2020-05-29 10:00:00' > `start`
) AS 'dp2'
FROM resources
结果如下:
| name | dp1 | dp2 |
| John | 1 | 1 |
| Anna | 0 | 0 |
这个比例不太好。如果我想确定整个星期的可用性,从08-17这将是70个子查询与当前的解决方案。
如何更优雅、更有效地确定n个给定日期段的资源可用性?
2条答案
按热度按时间rta7y2nd1#
我建议把句点放在行中而不是列中。这为您提供了一个纯sql解决方案的机会—否则您将需要动态sql。
如果您运行的是mysql 8.0,可以使用递归查询来枚举句点,
cross join
它与resources
得到表中的所有组合,然后把表与left join
.下面是一个查询,它将为您提供一周内所需的结果。您可以根据需要调整cte中的boudaries。
如果要经常运行此查询,应该考虑将cte的结果具体化为一个表(这是日历表的概念),然后在查询中使用这个表。
sr4lhrrt2#
一种可能的方法是创建一个临时表,在其中放置感兴趣的时段
periods_table
:然后将时段与来自预订和资源的值进行匹配: