2013-09-27 4 views
0

У меня есть запрос и данные, из которых мне нужно создать расписание.Запрос расписания SQL Server

Мой текущий запрос ниже:

SELECT contract.lect_code code1, 
     contract.coll_code code2, 
     line_date, 
     start_time, 
     end_time, 
     DATEPART(DW,line_date) AS day_number, 
     datename (dw,line_date) AS nameofday, 
     convert(varchar(8),start_time,108) AS start_time2, 
     convert(varchar(8),end_time,108) AS end_time2 
FROM bk_line 
INNER JOIN contract ON contract.contract_no = bk_line.contract_no 
WHERE line_date BETWEEN '2013/09/23' AND '2013/09/27' 
    AND coll_code = 'TEL01' 
    AND bk_line_status = 'CE' 
--And lect_code = 10430973 

Это дает мне данные в следующем формате: enter image description here

Мне нужен способ ломают раз в 15 минут слотов для каждого code1 и линии даты ,

Что-то вроде этого:

code1 | code2 | line_date | 0900worked | 0915worked | 0930worked |

где значения в 0900worked будет T или F.

-

EDIT

Мне нужно сгруппировать периоды от code1 и line_date. Поэтому в приведенном выше примере 1045096 работал с двумя сеансами на 2013/09/25. Мне нужно, чтобы обе сессии отображались в одной строке со всеми рассчитанными периодами.

ответ

2
select case 
     when convert(varchar(8),end_time,108) >= '09:15:00' 
      and convert(varchar(8),start_time,108) <= '09:00:00' 
      then 'T' 
      else 'F' 
     end as [0900worked] 
,  case 
     when convert(varchar(8),end_time,108) >= '09:30:00' 
      and convert(varchar(8),start_time,108) <= '09:15:00' 
      then 'T' 
      else 'F' 
     end as [0915worked] 
,  ... 
+1

+1 пятно на ... может быть большим вопросом, если на десять интервалов ... но полагает, что это природа зверя – whytheq

+0

Спасибо за это. Я добавил его в свой код, и он отлично работает. У меня другая проблема. Я опубликую его как редактирование. – evoandy

+1

Вы можете заключить фразу в 'max (case ... end) как [0900worked]'. Поскольку '' T '>' F'', это вернет true, если какая-либо строка в группе включала интервал 9: 00-9: 15. – Andomar

0

Может создать таблицу интервалов, используя что-то вроде этого:

;with t as 
(
select cast('00:00:00' as time) as intStart, 
0 as l 
union all 
select DATEADD(MINUTE, 15,intStart), 
l+1 
from t 
where intStart<='23:30:00' 
) 
select * 
from t; 

Затем вы можете использовать это, чтобы присоединиться на ваши данные и дает простор для поиска на любом из интервалов 15 минут в течение дня.

Затем вы можете использовать оператор выбора Andomar для любого из интервалов.

1

Вы можете сделать это таким образом, но я думаю, что есть лучшие способы проверить, работал ли кто-то в заданный интервал!

with "nums" 
as 
(
    select 1 as "value" 
    union all select "value" + 15 as "value" 
    from "nums" 
    where "value" <= 95*15 
) 
, "intervals" 
as 
(
    select 
    "id" = "value"/15 
    , "startDate" = dateadd(minute, "value" -1 , dateadd(year, datediff(year, 0, getdate()), 0)) 
    , "endDate" = dateadd(minute, "value" + 14, dateadd(year, datediff(year, 0, getdate()), 0)) 

from 
    "nums" 
) 
,"matched" 
as 
(
select 
    I.* 
    , D."id" as "code1" 
from 
    intervals as I 
left join "data" as D 
    on D."startDate" <= I."startDate" 
    and D."endDate" >= I."endDate" 
) 
select 
* 
from 
(
    select 
    "code1" 
    , "startDate" 
    from 
    "matched" 
) as Data 
    pivot(count(Data."startdate") 
    for "startDate" 
    in ( "2013-01-01 00:00:00.000" 
     , "2013-01-01 00:15:00.000" 
     , "2013-01-01 00:30:00.000" 
     , "2013-01-01 00:45:00.000" 
     , "2013-01-01 01:00:00.000" 
     , "2013-01-01 01:15:00.000" 
     , "2013-01-01 01:30:00.000" 
     , "2013-01-01 01:45:00.000" 
     , "2013-01-01 02:00:00.000" 
     , "2013-01-01 02:15:00.000" 
     , "2013-01-01 02:30:00.000" 
    )) as p 
where p.code1 is not null 

SQL-Fiddle

+0

Query дает 0 и 1 вместо T и F, но вы можете легко положить «случай, когда» вокруг него – Nico

+0

+1 как этот скрипт – whytheq