如何提取SQL字段中含'01'的子串以制作Tableau预约可用性报表
解决方案:从AOBLOC字段提取预约时段并标记状态
一、SQL层预处理(推荐,适合Tableau直接可视化)
核心思路是先生成8:00am至3:00pm的所有15分钟时段序列,再与你的业务表做交叉连接,逐个提取AOBLOC对应位置的子串并标记状态。输出的数据集可直接导入Tableau做可视化。
1. SQL Server 实现
用CTE生成时段序列,避免硬编码:
WITH TimeSlots AS ( SELECT 1 AS SlotNum, CAST('08:00:00' AS TIME) AS SlotTime UNION ALL SELECT SlotNum + 1, DATEADD(MINUTE, 15, SlotTime) FROM TimeSlots WHERE SlotTime < CAST('15:00:00' AS TIME) ) SELECT t.LocationID, -- 替换为你表中的地点标识字段 ts.SlotTime, CASE WHEN SUBSTRING(t.AOBLOC, 2*ts.SlotNum - 1, 2) = '01' THEN '已预约' ELSE '可预约' END AS AppointmentStatus FROM YourTable t -- 替换为你的业务表名 CROSS JOIN TimeSlots ts ORDER BY t.LocationID, ts.SlotTime
2. MySQL 实现
用临时表生成时段序列:
-- 初始化变量生成时段 SET @slot_num = 0; SET @slot_time = '08:00:00'; -- 创建临时存储时段的表 CREATE TEMPORARY TABLE TimeSlots ( SlotNum INT, SlotTime TIME ); -- 循环生成所有时段 WHILE @slot_time <= '15:00:00' DO SET @slot_num = @slot_num + 1; INSERT INTO TimeSlots VALUES (@slot_num, @slot_time); SET @slot_time = ADDTIME(@slot_time, '00:15:00'); END WHILE; -- 关联业务表生成状态数据 SELECT t.LocationID, -- 替换为你表中的地点标识字段 ts.SlotTime, CASE WHEN SUBSTRING(t.AOBLOC, 2*ts.SlotNum - 1, 2) = '01' THEN '已预约' ELSE '可预约' END AS AppointmentStatus FROM YourTable t -- 替换为你的业务表名 CROSS JOIN TimeSlots ts ORDER BY t.LocationID, ts.SlotTime;
二、Tableau 内直接处理(适合无法修改SQL的场景)
如果只能用现有SQL输出的数据集,可在Tableau内完成拆分和标记:
- 创建时段维度表:手动制作包含
SlotNum(1-28)和SlotTime(8:00am至3:00pm的15分钟间隔时间)的Excel/CSV表,导入Tableau。 - 交叉连接数据集:将业务表与时段维度表做交叉连接(需数据源支持,或用数据融合)。
- 创建计算字段:
IF SUBSTRING([AOBLOC], 2*[SlotNum]-1, 2) = '01' THEN '已预约' ELSE '可预约' END - 可视化配置:用热力图或表格,将
LocationID设为行,SlotTime设为列,AppointmentStatus设为颜色标记,即可展示各地点的预约可用性。
三、关于硬编码CASE语句的说明
硬编码CASE语句虽然可行,但维护性极差(28个时段需写28段UNION ALL),示例片段如下,不推荐使用:
SELECT LocationID, '08:00:00' AS SlotTime, CASE WHEN SUBSTRING(AOBLOC,1,2)='01' THEN '已预约' ELSE '可预约' END AS AppointmentStatus UNION ALL SELECT LocationID, '08:15:00' AS SlotTime, CASE WHEN SUBSTRING(AOBLOC,3,2)='01' THEN '已预约' ELSE '可预约' END AS AppointmentStatus -- ... 重复至15:00:00的时段
内容的提问来源于stack exchange,提问作者Martin
相关产品推荐
相关产品推荐

