SQL查询中的DateDiff和Case运算符

时间:2019-04-06 11:49:53

标签: sql sql-server datediff

我正在尝试创建一个报告,以帮助我们确定我们在按时发送订单时的工作方式,但是对于SQL来说还是一个新手,并且不确定如何实现我所需要的。

我们的目标是发货在同一天中午12点之前的工作日发出的订单。对于在工作日或周末的中午12点之后下达的订单,我们的目标是在下一个工作日(星期一至星期五)发货。

我有一个初始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和AND等实现,但不确定如何做到。

我使用了以下代码,我认为这些代码现在可以正常工作,但是对于获得有关是否可以改进此代码的任何反馈都是很好的。

  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 :(得分:0)

以下是用于针对您所陈述的条件计算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设置无关。

您可能还需要考虑将公共假期考虑在内,并为此添加条件。