从SLA中排除周末日期

时间:2014-04-29 14:56:39

标签: sql-server-2012

我有一个与外联网报告相关的查询,我最近被要求调整以排除SLA计算的周末 - 我一无所知 - 有人可以帮忙吗?

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

/*
Modified Date:  Modified By:    Description:
19/03/2014      RC              Created for extranet report 'IA Booking to IA timings'
29/04/2014      MC              Adjusted SLAs
*/

ALTER PROCEDURE [dbo].[rex_IABookingToIA] 
@Start_Date DATETIME,
@End_Date DATETIME

AS


set dateformat dmy
--declare @Start_Date DATETIME
--declare @End_Date DATETIME
--set @Start_Date = '10/03/2014'
--set @End_Date = '11/03/2014'


SELECT 
    AppointmentBookedBy
    ,count(CaseID) AS [Total IA Bookings]
    ,SUM(CASE   WHEN datediff(dd,AppointmentBooked_DateTime,[Date]) BETWEEN 0 and 2 
            THEN 1 ELSE 0
        END) AS [0 - 2 days]
    ,SUM(CASE   WHEN datediff(dd,AppointmentBooked_DateTime,[Date]) BETWEEN 3 and 5 
            THEN 1 ELSE 0
        END) AS [3 - 5 days]    
    ,SUM(CASE   WHEN datediff(dd,AppointmentBooked_DateTime,[Date]) BETWEEN 6 and 7 
            THEN 1 ELSE 0
        END) AS [6 - 7 days]
    ,SUM(CASE   WHEN datediff(dd,AppointmentBooked_DateTime,[Date]) > 7 
            THEN 1 ELSE 0
        END) AS [8 days and over]
INTO #IABookings                        
FROM TICCSMI.dbo.array_PW_appointments[dbo]
WHERE AppointmentBooked_DateTime >= @Start_Date    
and AppointmentBooked_DateTime < @End_Date
and [Type]='IA'
and [Department Booked By] = 'Physioworld Booking Team'
GROUP BY AppointmentBookedBy
ORDER BY AppointmentBookedBy


SELECT 
    AppointmentBookedBy AS [Agent]
    ,[Total IA Bookings]
    ,[0 - 4 days]
    ,CASE WHEN ([0 - 2 days] = 0 OR [Total IA Bookings] = 0) THEN CAST(0 AS DECIMAL (10,2))
        ELSE CAST(100.00*[0 - 2 days]/[Total IA Bookings] AS DECIMAL (10,2))
    END AS [%]
    ,[3 - 5 days]
    ,CASE WHEN ([3 - 5 days] = 0 OR [Total IA Bookings] = 0) THEN CAST(0 AS DECIMAL (10,2))
        ELSE CAST(100.00*[3 - 5 days]/[Total IA Bookings] AS DECIMAL (10,2))
    END AS [%]
    ,[6 - 7 days]
    ,CASE WHEN ([6 - 7 days] = 0 OR [Total IA Bookings] = 0) THEN CAST(0 AS DECIMAL (10,2))
        ELSE CAST(100.00*[6 - 7 days]/[Total IA Bookings] AS DECIMAL (10,2))
    END AS [%]
    ,[8 days and over]
    ,CASE WHEN ([8 days and over] = 0 OR [Total IA Bookings] = 0) THEN CAST(0 AS DECIMAL     (10,2))
        ELSE CAST(100.00*[8 days and over]/[Total IA Bookings] AS DECIMAL (10,2))
    END AS [%]
FROM #IABookings
ORDER BY AppointmentBookedBy

所以 - 如果在周末预订,我需要接受,但不包括周末参与SLA时间。

提前致谢

1 个答案:

答案 0 :(得分:0)

我过去曾使用递归CTE来完成此任务。

我们的想法是找到@Start_Date之前的星期六作为种子来构建所有其他周末日期的列表,直到@End_Date

在报告查询中,{C}周末日期为LEFT JOIN,位于AppointmentBooked_DateTime和Date之间。

因为我们使用了LEFT JOIN,所以任何不在周末的约会都会为该列提供NULL,而跨越周末的约会每周末会有一条记录。 COUNT并不计算NULL,因此计算不包括周末的SLA只需从COUNT(weekendDate)中减去DATEDIFF即可。

这里有一些带有几个测试用例的SQL,我认为这些测试用例与您一直在寻找:

declare @Start_Date DATE = '20140404'
declare @End_Date DATE = '20140503'
SET DATEFIRST 7 -- just in case
declare @SaturdayBeforeStartDate date
select @SaturdayBeforeStartDate = dateadd(day, -datepart(weekday, @Start_date), @Start_date)

declare @array_PW_appointments table(CaseID int, AppointmentBookedBy varchar(20), AppointmentBooked_DateTime datetime, [Date] datetime, [Type] char(2), [Department Booked By] varchar(50))
insert @array_PW_appointments values
-- test case 1: 8 days, spanning one weekend.  This should be 6 days ex. weekend
(1, 'Jane','20140408','20140416','IA','Physioworld Booking Team'),
-- test case 2: 3 days, no weekend.  Should be 3 days.
(2, 'Jane','20140421','20140424','IA','Physioworld Booking Team'),
-- test case 3: 14 days, two full weekends.  Should be 10 days.
(3, 'Jane','20140409','20140423','IA','Physioworld Booking Team'),
-- test case 4: 2 days, starting on a Sunday.  Should be 1 day
(4, 'Jane','20140427','20140428','IA','Physioworld Booking Team')

;with weekend_cte as (
    select @SaturdayBeforeStartDate as weekendDate
    union all
    -- if it's Saturday, add 1 day; if Sunday, add 6 to get to the following Saturday
    select dateadd(day, case DATEPART(weekday, weekendDate) when 7 then 1 when 1 then 6 end, weekendDate)
    from weekend_cte
    where weekendDate <= @End_Date
), aged as (
    select CaseID, AppointmentBookedBy, AppointmentBooked_DateTime, [Date]
    -- excluding weekends is as simple as subtracting the # of rows the left join actually hits on
    , datediff(dd,AppointmentBooked_DateTime,[Date])-count(weekendDate) as age_exweekend
    FROM @array_PW_appointments a
    -- left join so we don't miss Cases without a weekend in between
    left join weekend_cte w on w.weekendDate >= AppointmentBooked_DateTime and w.weekendDate <= [Date]
    WHERE AppointmentBooked_DateTime >= @Start_Date    
    and AppointmentBooked_DateTime < @End_Date
    and [Type]='IA'
    and [Department Booked By] = 'Physioworld Booking Team'
    group by CaseID, AppointmentBookedBy, AppointmentBooked_DateTime, [Date] 
), bucketed_exweekend as (
    SELECT AppointmentBookedBy
    ,count(CaseID) AS [Total IA Bookings]
    ,SUM(CASE   WHEN age_exweekend BETWEEN 0 and 2 THEN 1 ELSE 0 END) AS [0 - 2 days]
    ,SUM(CASE   WHEN age_exweekend BETWEEN 3 and 5 THEN 1 ELSE 0 END) AS [3 - 5 days]    
    ,SUM(CASE   WHEN age_exweekend BETWEEN 6 and 7 THEN 1 ELSE 0 END) AS [6 - 7 days]
    ,SUM(CASE   WHEN age_exweekend > 7  THEN 1 ELSE 0 END) AS [8 days and over]
    FROM aged
    GROUP BY AppointmentBookedBy
)
select AppointmentBookedBy, [Total IA Bookings]
, [0 - 2 days], CASE WHEN ([Total IA Bookings] = 0) THEN 0.0 ELSE CAST(100.00*[0 - 2 days]/[Total IA Bookings] AS DECIMAL (10,2)) END AS [%]
, [3 - 5 days], CASE WHEN ([Total IA Bookings] = 0) THEN 0.0 ELSE CAST(100.00*[3 - 5 days]/[Total IA Bookings] AS DECIMAL (10,2)) END AS [%]
, [6 - 7 days], CASE WHEN ([Total IA Bookings] = 0) THEN 0.0 ELSE CAST(100.00*[6 - 7 days]/[Total IA Bookings] AS DECIMAL (10,2)) END AS [%]
, [8 days and over], CASE WHEN ([Total IA Bookings] = 0) THEN 0.0 ELSE CAST(100.00*[8 days and over]/[Total IA Bookings] AS DECIMAL (10,2)) END AS [%]
from bucketed_exweekend