技术问询:如何判断顾客到访时段与1小时时间块重叠并计算餐厅时段桌数
餐厅跨时段桌数统计解决方案
核心问题:跨夜间时段重叠判断
你需要判断顾客用餐时段与目标1小时区间是否重叠,难点在跨天场景(比如23:00进店次日2:00离店,需覆盖23-00、00-01、01-02三个时段)。关键是必须给Time_In和Time_Out补充完整日期(仅时间无法区分跨天)。
方案1:公式实现重叠判断(Excel/Google Sheets)
假设目标时段的Target_Start和Target_End是带日期的完整时间戳(如2024-05-20 23:00:00和2024-05-21 00:00:00),用以下公式判断单个顾客是否占用该时段:
=IF(Time_Out < Time_In, OR(Time_In < Target_End, Time_Out + 1 > Target_Start), AND(Time_In < Target_End, Time_Out > Target_Start) )
- 跨天场景(
Time_Out < Time_In):只要顾客进店早于时段结束,或离店时间+1天晚于时段开始,即判定重叠 - 非跨天场景:用标准区间重叠逻辑(进店早于时段结束,且离店晚于时段开始)
标记完所有时段的Yes/No后,用COUNTIF按日期+时段统计即可得到对应时段的占用桌数。
方案2:Power Query/脚本拆分时段(高效处理大数据)
如果数据量较大,先拆分每个顾客的用餐时段为覆盖的所有1小时区间,再统计:
- 用Power Query(Excel)或Google Apps Script,将
Time_In到Time_Out(跨天则自动给Time_Out加1天)拆分为每1小时一条记录,每条记录标记对应日期和时段 - 对每个时段的
Customer ID去重(同一顾客同一时段只算一桌) - 用数据透视表按日期行、时段列汇总,直接生成每日各时段占用桌数的表格
方案3:SQL批量处理(数据库存储数据时)
若数据存在数据库,用SQL生成所有时段并关联判断更高效:
WITH hourly_windows AS ( -- 生成6个月内所有1小时时段 SELECT DATE_ADD('2024-01-01', INTERVAL n HOUR) AS window_start, DATE_ADD('2024-01-01', INTERVAL n+1 HOUR) AS window_end, DATE(window_start) AS visit_date, CONCAT(LPAD(HOUR(window_start),2,'0'), ":00-", LPAD(HOUR(window_end),2,'0'), ":00") AS time_slot FROM (SELECT 0 n UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 UNION ALL SELECT 10 UNION ALL SELECT 11 UNION ALL SELECT 12 UNION ALL SELECT 13 UNION ALL SELECT 14 UNION ALL SELECT 15 UNION ALL SELECT 16 UNION ALL SELECT 17 UNION ALL SELECT 18 UNION ALL SELECT 19 UNION ALL SELECT 20 UNION ALL SELECT 21 UNION ALL SELECT 22 UNION ALL SELECT 23) hours WHERE DATE_ADD('2024-01-01', INTERVAL n HOUR) <= '2024-06-30' ) SELECT hw.visit_date, hw.time_slot, COUNT(DISTINCT rv.customer_id) AS occupied_tables FROM hourly_windows hw LEFT JOIN restaurant_visits rv ON -- 非跨天重叠 (rv.time_in < hw.window_end AND rv.time_out > hw.window_start) -- 跨天重叠 OR (rv.time_out < rv.time_in AND (rv.time_in < hw.window_end OR rv.time_out + INTERVAL 1 DAY > hw.window_start)) GROUP BY hw.visit_date, hw.time_slot ORDER BY hw.visit_date, hw.window_start;
当前思路的可行性
你用Time In/Out + 各时段Yes/No标记的思路完全可行,之前卡壳是因为没处理跨天的日期逻辑。只要给所有时间字段补全日期,用方案1的公式就能解决标记问题,后续统计就简单了。如果数据量小,这个方法足够直观;数据量大的话,方案2或3效率更高。
内容的提问来源于stack exchange,提问作者Abeworld
相关产品推荐
相关产品推荐

