Оператор DateDiff и Case в запросе SQL - PullRequest
0 голосов
/ 06 апреля 2019

Я пытаюсь создать отчет, который поможет нам определить, как мы делаем своевременную доставку заказов, но я совершенно новичок в SQL и не совсем уверен, как достичь того, что мне нужно.

Мыстремиться к отправке заказов, которые размещены в будний день до 12 вечера того же дня.Для заказов, размещенных после 12:00 в рабочий день или в выходные дни, мы планируем отправить заказ на следующий рабочий день (пн-пт).

У меня есть исходный запрос SQL, который показывает все правильные столбцы иимеет оператора CASE, но он просто проверяет, был ли заказ отправлен в течение 24 часов, но не учитывает, когда заказ был размещен или в какой день.

CASE WHEN DATEDIFF(day,order_datetime,delivery_datetime)<=1
    THEN 1
    ELSE 0
    END AS Ontime_infull

Параметр Ontime_infull должен быть равен 1, если мы достигнем цели доставки, и 0, если нам не удастся.Я уверен, что это может быть достигнуто с помощью вложенных CASE, WHEN, и т. Д., Но просто не уверен, как это сделать.

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

  CASE 
    WHEN DATENAME(dw,order_header_detail.ohd_input_datetime) = 'Monday' AND DATEPART(hh,order_header_detail.ohd_input_datetime) < 12 AND DATEDIFF(Day,order_header_detail.ohd_input_datetime,delivery_header.dh_datetime) =0 THEN 1
    WHEN DATENAME(dw,order_header_detail.ohd_input_datetime) = 'Monday' AND DATEPART(hh,order_header_detail.ohd_input_datetime) >= 12 AND DATEDIFF(Day,order_header_detail.ohd_input_datetime,delivery_header.dh_datetime) <=1 THEN 1
    WHEN DATENAME(dw,order_header_detail.ohd_input_datetime) = 'Tuesday' AND DATEPART(hh,order_header_detail.ohd_input_datetime) < 12 AND DATEDIFF(Day,order_header_detail.ohd_input_datetime,delivery_header.dh_datetime) =0 THEN 1
    WHEN DATENAME(dw,order_header_detail.ohd_input_datetime) = 'Tuesday' AND DATEPART(hh,order_header_detail.ohd_input_datetime) >= 12 AND DATEDIFF(Day,order_header_detail.ohd_input_datetime,delivery_header.dh_datetime) <=1 THEN 1  
    WHEN DATENAME(dw,order_header_detail.ohd_input_datetime) = 'Wednesday' AND DATEPART(hh,order_header_detail.ohd_input_datetime) < 12 AND DATEDIFF(Day,order_header_detail.ohd_input_datetime,delivery_header.dh_datetime) =0 THEN 1
    WHEN DATENAME(dw,order_header_detail.ohd_input_datetime) = 'Wednesday' AND DATEPART(hh,order_header_detail.ohd_input_datetime) >= 12 AND DATEDIFF(Day,order_header_detail.ohd_input_datetime,delivery_header.dh_datetime) <=1 THEN 1
    WHEN DATENAME(dw,order_header_detail.ohd_input_datetime) = 'Thursday' AND DATEPART(hh,order_header_detail.ohd_input_datetime) < 12 AND DATEDIFF(Day,order_header_detail.ohd_input_datetime,delivery_header.dh_datetime) =0 THEN 1
    WHEN DATENAME(dw,order_header_detail.ohd_input_datetime) = 'Thursday' AND DATEPART(hh,order_header_detail.ohd_input_datetime) >= 12 AND DATEDIFF(Day,order_header_detail.ohd_input_datetime,delivery_header.dh_datetime) <=1 THEN 1
    WHEN DATENAME(dw,order_header_detail.ohd_input_datetime) = 'Friday' AND DATEPART(hh,order_header_detail.ohd_input_datetime) < 12 AND DATEDIFF(Day,order_header_detail.ohd_input_datetime,delivery_header.dh_datetime) =0 THEN 1
    WHEN DATENAME(dw,order_header_detail.ohd_input_datetime) = 'Friday' AND DATEPART(hh,order_header_detail.ohd_input_datetime) >= 12 AND DATEDIFF(Day,order_header_detail.ohd_input_datetime,delivery_header.dh_datetime) <=3 THEN 1
    WHEN DATENAME(dw,order_header_detail.ohd_input_datetime) = 'Saturday' AND DATEDIFF(Day,order_header_detail.ohd_input_datetime,delivery_header.dh_datetime) <=2 THEN 1
    WHEN DATENAME(dw,order_header_detail.ohd_input_datetime) = 'Sunday' AND DATEDIFF(Day,order_header_detail.ohd_input_datetime,delivery_header.dh_datetime) <=1 THEN 1
    ELSE 0
END AS Ontime_infull

Любая помощь будет принята с благодарностью.

1 Ответ

0 голосов
/ 08 апреля 2019

Вот более короткая форма для вычисления флага Ontime_infull для указанных условий:

case when
 -- same day delivery is always OK
 (datediff(dd, order_datetime, delivery_datetime) = 0) 
 -- next day deliver is OK if order is after midday
  or ((datepart(hh, order_datetime) >= 12 and datediff(dd, order_datetime, delivery_datetime) = 1))
 -- delivery on the following Monday is OK if ordered after midday on Friday
  or (
      (datepart(hh, order_datetime) >= 12 and datediff(dd, order_datetime, delivery_datetime) <= 3)
       and (((datepart(dw, order_datetime) + @@DATEFIRST + 5) % 7 + 1) >= 5) -- Friday or later
       and (((datepart(dw, delivery_datetime) + @@DATEFIRST + 5) % 7 + 1) = 1)  -- Monday
     )      
then 1
else 0

Конструкция datepart(dw, order_datetime) + @@DATEFIRST + 5) % 7 + 1 вычисляет номер дня недели от 1 (понедельник) до 7 (воскресенье)независимо от настройки SET DATEFIRST.

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

...