Используйте Calendar.Date для создания фиктивных данных - PullRequest
0 голосов
/ 27 июня 2019

Я пытаюсь создать таблицу расписаний, используя 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,,

A 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?

Ответы [ 2 ]

1 голос
/ 27 июня 2019

Похоже, вы можете подать заявку и взять максимальное время начала:

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
1 голос
/ 27 июня 2019

Вы, кажется, хотите что-то вроде этого:

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,

Здесь - это дБ <> скрипка.

Вы можете использовать таблицу календаря, но я нене вижу необходимости в этом для примера.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...