计算卡车服务日期:基于SQL Server表的时间与服务日数据
计算SQL Server中卡车的服务日期
嘿,我来帮你搞定这个需求!首先咱们先确认下你的表(假设表名叫TruckServices)的结构和示例数据:
CREATE TABLE TruckServices ( TruckCode VARCHAR(10), ServiceHour TIME, Monday BIT, Tuesday BIT, Wednesday BIT, Thursday BIT, Friday BIT, Saturday BIT ); INSERT INTO TruckServices VALUES ('Route1', '17:00', 1, 0, 1, 0, 1, 0), ('Route2', '09:30', 1, 1, 1, 1, 1, 1), ('Route3', '14:30', 0, 1, 0, 1, 0, 0);
根据你的需求,我准备了两种常见的实现方案,分别对应不同的输出场景:
方案1:将每个服务日期拆分为单独行
如果你需要把每个服务的星期几作为独立记录(方便后续关联日期表计算具体的日历日期),可以用UNPIVOT操作把列转成行:
SELECT ts.TruckCode, ts.ServiceHour, up.ServiceDay FROM TruckServices ts UNPIVOT ( IsServiceDay FOR ServiceDay IN (Monday, Tuesday, Wednesday, Thursday, Friday, Saturday) ) up WHERE up.IsServiceDay = 1 ORDER BY ts.TruckCode;
执行后会得到这样的结果:
| TruckCode | ServiceHour | ServiceDay |
|---|---|---|
| Route1 | 17:00:00 | Monday |
| Route1 | 17:00:00 | Wednesday |
| Route1 | 17:00:00 | Friday |
| Route2 | 09:30:00 | Monday |
| Route2 | 09:30:00 | Tuesday |
| Route2 | 09:30:00 | Wednesday |
| Route2 | 09:30:00 | Thursday |
| Route2 | 09:30:00 | Friday |
| Route2 | 09:30:00 | Saturday |
| Route3 | 14:30:00 | Tuesday |
| Route3 | 14:30:00 | Thursday |
方案2:将服务日期合并为逗号分隔的字符串
如果是要把每个卡车的服务日期整合成一个字符串(比如用于报表展示),分两种情况处理:
适用于SQL Server 2017及以上版本
可以直接用STRING_AGG这个便捷的字符串聚合函数:
SELECT TruckCode, ServiceHour, STRING_AGG(ServiceDay, ', ') AS ServiceDays FROM ( SELECT ts.TruckCode, ts.ServiceHour, up.ServiceDay FROM TruckServices ts UNPIVOT ( IsServiceDay FOR ServiceDay IN (Monday, Tuesday, Wednesday, Thursday, Friday, Saturday) ) up WHERE up.IsServiceDay = 1 ) AS ServiceDetails GROUP BY TruckCode, ServiceHour ORDER BY TruckCode;
输出结果:
| TruckCode | ServiceHour | ServiceDays |
|---|---|---|
| Route1 | 17:00:00 | Monday, Wednesday, Friday |
| Route2 | 09:30:00 | Monday, Tuesday, Wednesday, Thursday, Friday, Saturday |
| Route3 | 14:30:00 | Tuesday, Thursday |
适用于SQL Server 2016及以下版本
低版本没有STRING_AGG,可以用STUFF+FOR XML PATH的组合来实现字符串拼接:
SELECT ts.TruckCode, ts.ServiceHour, STUFF(( SELECT ', ' + up.ServiceDay FROM TruckServices ts_inner UNPIVOT ( IsServiceDay FOR ServiceDay IN (Monday, Tuesday, Wednesday, Thursday, Friday, Saturday) ) up WHERE ts_inner.TruckCode = ts.TruckCode AND up.IsServiceDay = 1 FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)'), 1, 2, '') AS ServiceDays FROM TruckServices ts GROUP BY ts.TruckCode, ts.ServiceHour ORDER BY ts.TruckCode;
这个查询的结果和上面STRING_AGG的版本完全一致。
思路简单说明
核心逻辑就是先用UNPIVOT把原来横向的星期几列转换成纵向的行记录,然后筛选出标记为1(即提供服务)的日期,之后要么直接输出这些行,要么根据需求把同一个卡车的服务日期聚合起来。这样就能完美得到你需要的卡车服务日期啦!
内容的提问来源于stack exchange,提问作者ahmet kocadogan
相关产品推荐
相关产品推荐

