我正在尝试创建时间表表,使用Calendar.Date
生成空的“单元格”。
查询:
select c.Date, d.DriverId, d.RouteId, d.StartTime
FROM Calendar c
left outer join
(
select 'ABC' DriverId, 101 RouteId, cast('2019-08-26 08:30:00.000' as datetime) StartTime
union all
select 'ABC' DriverId, 101 RouteId, cast('2019-08-29 08:30:00.000' as datetime) StartTime
union all
select 'DEF' DriverId, 201 RouteId, cast('2019-08-27 11:30:00.000' as datetime) StartTime
) d ON d.StartTime >= c.Date AND d.StartTime < DATEADD(DAY, 1, c.Date)
WHERE 1=1
and c.date between '08/26/19' and '08/29/19'
结果:
Date,DriverId,RouteId,StartTime
2019-08-26 00:00:00.000,ABC,101,2019-08-26 08:30:00.000
2019-08-27 00:00:00.000,DEF,201,2019-08-27 11:30:00.000
2019-08-28 00:00:00.000,,,
2019-08-29 00:00:00.000,ABC,101,2019-08-29 08:30:00.000
所需:
Date,DriverId,RouteId,StartTime
2019-08-26 00:00:00.000,ABC,101,2019-08-26 08:30:00.000
2019-08-26 00:00:00.000,DEF,,
2019-08-27 00:00:00.000,ABC,,
2019-08-27 00:00:00.000,DEF,201,2019-08-27 11:30:00.000
2019-08-28 00:00:00.000,ABC,,
2019-08-28 00:00:00.000,DEF,,
2019-08-29 00:00:00.000,ABC,101,2019-08-29 08:30:00.000
2019-08-29 00:00:00.000,DEF,,
一个CROSS JOIN
:
select c.Date, d.DriverId, d.RouteId, d.StartTime
FROM Calendar c
cross join
(
select 'ABC' DriverId, 101 RouteId, cast('2019-08-26 08:30:00.000' as datetime) StartTime
union all
select 'ABC' DriverId, 101 RouteId, cast('2019-08-29 08:30:00.000' as datetime) StartTime
union all
select 'DEF' DriverId, 201 RouteId, cast('2019-08-27 11:30:00.000' as datetime) StartTime
) d
WHERE 1=1
and c.date between '08/26/19' and '08/29/19'
没有产生期望的结果:
Date,DriverId,RouteId,StartTime
2019-08-26 00:00:00.000,ABC,101,2019-08-26 08:30:00.000
2019-08-26 00:00:00.000,ABC,101,2019-08-29 08:30:00.000
2019-08-26 00:00:00.000,DEF,201,2019-08-27 11:30:00.000
2019-08-27 00:00:00.000,ABC,101,2019-08-26 08:30:00.000
2019-08-27 00:00:00.000,ABC,101,2019-08-29 08:30:00.000
2019-08-27 00:00:00.000,DEF,201,2019-08-27 11:30:00.000
2019-08-28 00:00:00.000,ABC,101,2019-08-26 08:30:00.000
2019-08-28 00:00:00.000,ABC,101,2019-08-29 08:30:00.000
2019-08-28 00:00:00.000,DEF,201,2019-08-27 11:30:00.000
2019-08-29 00:00:00.000,ABC,101,2019-08-26 08:30:00.000
2019-08-29 00:00:00.000,ABC,101,2019-08-29 08:30:00.000
2019-08-29 00:00:00.000,DEF,201,2019-08-27 11:30:00.000
是否有一种无需诉诸T/SQL
就能获得结果的方法?
答案 0 :(得分:1)
您似乎想要这样的东西:
select c.dte, d.DriverId, drs.RouteId, drs.StartTime
from (values ('ABC'), ('DEF')) d(DriverId) cross join
(values (convert(date, '2019-08-26')), (convert(date, '2019-08-27')), (convert(date, '2019-08-28')), (convert(date, '2019-08-29'))
) c(dte) left join
(values ('ABC', 101, cast('2019-08-26 08:30:00.000' as datetime)),
('ABC', 101, cast('2019-08-29 08:30:00.000' as datetime)),
('DEF', 201, cast('2019-08-27 11:30:00.000' as datetime)
) drs(DriverId, RouteId, StartTime)
on drs.driverId = d.driverId and
drs.StartTime >= c.dte and drs.StartTime < dateadd(day, 1, c.dte)
order by dte, driverid,
Here是db <>小提琴。
您可以使用日历表,但对于本示例,我认为不需要。
答案 1 :(得分:1)
看起来您可以交叉申请并获得最长的开始时间:
SELECT
c.val,
d.driverid,
MAX(CASE WHEN c.val <> CAST(CAST(d.starttime AS DATE) AS DATETime) THEN NULL else d.routeid end) AS routeid,
MAX(CASE WHEN c.val <> CAST(CAST(d.starttime AS DATE) AS DATETime) THEN NULL else d.starttime end) AS start_time
FROM calendar c
CROSS APPLY driverstuff d
GROUP BY c.val, d.driverid
ORDER BY c.val