我看了一下论坛,但是找不到任何足够的内容适合我的场景,所以这里就是这样。
我有以下查询,该查询计算在定义的日期期间内跨多个表的一组条目的平均时间。 3种类型(IR,SR,CR)都链接到一个表(WorkItems)。我平均时间的查询如下。 (参数用于报告服务和日期选择器)
Select
WIAvgAssign = AVG(
Case When WI.id Like 'IR%' Then DATEDIFF(hour,wi.CreatedDate,IR.FirstAssignedDate)
When WI.Id Like 'SR%' Then DATEDIFF(hour,wi.CreatedDate,SR.FirstAssignedDate)
When WI.Id Like 'SR%' Then DATEDIFF(hour,wi.CreatedDate,CR.FirstAssignedDate)
END),
IRAvgAssign = AVG(DATEDIFF(hour,wi.CreatedDate,IR.FirstAssignedDate)),
SRAvgAssign = AVG(DATEDIFF(hour,wi.CreatedDate,SR.FirstAssignedDate)),
CRAvgAssign = AVG(DATEDIFF(hour,wi.CreatedDate,CR.FirstAssignedDate))
from WorkItemDimvw WI
Left Outer Join IncidentDimvw IR on WI.EntityDimKey=IR.EntityDimKey
Left Outer Join ServiceRequestDimvw SR on WI.EntityDimKey=SR.EntityDimKey
Left Outer Join ChangeRequestDimvw CR on WI.EntityDimKey=CR.EntityDimKey
Where (IR.ResolvedDate >= @StartDate AND IR.ResolvedDate < @EndDate) OR
(SR.CompletedDate >= @StartDate AND SR.CompletedDate < @EndDate) OR
(CR.ActualEndDate >=@StartDate AND CR.ActualEndDate < @EndDate)
我有一张表格,其中包含每周的每一天以及该特定日期的营业时间(日期是创建条目的时间,它只是我感兴趣的时间),周末的价值是空白的。
Day Start Time End Time
Monday 2014-03-06 09:00:00.000 2014-03-06 17:00:00.000
Tuesday 2014-03-06 09:00:00.000 2014-03-06 17:00:00.000
Wednesday 2014-03-06 09:00:00.000 2014-03-06 17:00:00.000
Thursday 2014-03-06 09:00:00.000 2014-03-06 17:00:00.000
Friday 2014-03-06 09:00:00.000 2014-03-06 17:00:00.000
Saturday NULL NULL
Sunday NULL NULL
我目前获得的平均小时数与营业时间无关,因此我希望能够在办公室关闭时剥离并提供更准确的平均值。
由于
编辑 - 我已经提出了这个问题,因为我已经在查询中手动指定了非工作时间的数量并在周末的计算中添加了,所以效率有点低。看一下个人记录,我认为这是正确的。我暂时取出了CR计算
Declare @StartDate datetime
Declare @EndDate datetime
Set @StartDate = '2015/01/01'
Set @EndDate = '2015/12/31'
Select
AVG(
CASE WHEN CAST(wi.createddate as date) =
CAST(
CASE
WHEN WI.Id like 'IR%' then CASE WHEN ir.FirstAssignedDate !=NULL THEN ir.firstassigneddate else GETDATE() END
WHEN WI.Id like 'SR%' then CASE WHEN sr.firstassigneddate !=NULL THEN Sr.firstassigneddate else GETDATE() END
END
as date)
THEN DATEDIFF(HOUR,wi.CreatedDate,
CASE
WHEN WI.Id like 'IR%' then CASE WHEN ir.FirstAssignedDate !=NULL THEN ir.firstassigneddate else GETDATE() END
WHEN WI.Id like 'SR%' then CASE WHEN sr.firstassigneddate !=NULL THEN Sr.firstassigneddate else GETDATE() END
END)
ELSE (DATEDIFF(hour,wi.CreatedDate,DATEADD(hour,-15*DATEDIFF(day,wi.CreatedDate,CASE
WHEN WI.Id like 'IR%' then CASE WHEN ir.FirstAssignedDate !=NULL THEN ir.firstassigneddate else GETDATE() END
WHEN WI.Id like 'SR%' then CASE WHEN sr.firstassigneddate !=NULL THEN Sr.firstassigneddate else GETDATE() END
END),CASE
WHEN WI.Id like 'IR%' then CASE WHEN ir.FirstAssignedDate !=NULL THEN ir.firstassigneddate else GETDATE() END
WHEN WI.Id like 'SR%' then CASE WHEN sr.firstassigneddate !=NULL THEN Sr.firstassigneddate else GETDATE() END
END)))-48*DATEDIFF(wk,wi.CreatedDate,CASE
WHEN WI.Id like 'IR%' then CASE WHEN ir.FirstAssignedDate !=NULL THEN ir.firstassigneddate else GETDATE() END
WHEN WI.Id like 'SR%' then CASE WHEN sr.firstassigneddate !=NULL THEN Sr.firstassigneddate else GETDATE() END
END)
END)
from WorkItemDimvw WI
Left Outer Join IncidentDimvw IR on WI.EntityDimKey=IR.EntityDimKey
Left Outer Join ServiceRequestDimvw SR on WI.EntityDimKey=SR.EntityDimKey
Left Outer Join ChangeRequestDimvw CR on WI.EntityDimKey=CR.EntityDimKey
WHERE (wi.Id like 'IR%' or WI.ID like 'SR%') AND
((IR.ResolvedDate >=@StartDate AND IR.ResolvedDate < @EndDate) OR
(Sr.CompletedDate >=@StartDate AND SR.CompletedDate < @EndDate))
答案 0 :(得分:1)
经过多个小时的调整后,我想出了以下内容,我90%肯定是对的。如果有任何方法可以优化查询,那将会有所帮助。
Declare @StartDate datetime
Declare @EndDate datetime
Set @StartDate = '2016/01/01'
Set @EndDate = '2016/12/31'
SELECT
WIAvgAssign = AVG(
Case
When id Like 'IR%' Then DATEDIFF(hour,NormalizedCreatedDate,NormalizedIRAssignedDate)
-(DATEDIFF(wk,normalizedcreateddate,NormalizedIRAssignedDate)*48)
-((DATEDIFF(day,normalizedcreateddate,NormalizedIRAssignedDate)-(DATEDIFF(wk,normalizedcreateddate,NormalizedIRAssignedDate)*2))*14)
-(Case When DateName(dw,NormalizedCreatedDate) = 'Sunday' THEN 24 ELSE 0 END)
-(Case When DATENAME(dw,NormalizedIRAssignedDate) = 'Saturday' THEN 24 ELSE 0 END)
When id Like 'SR%' Then DATEDIFF(hour,NormalizedCreatedDate,NormalizedSRAssignedDate)
-(DATEDIFF(wk,normalizedcreateddate,NormalizedSRAssignedDate)*48)
-((DATEDIFF(day,normalizedcreateddate,NormalizedSRAssignedDate)-(DATEDIFF(wk,normalizedcreateddate,NormalizedSRAssignedDate)*2))*14)
-(Case When DateName(dw,NormalizedCreatedDate) = 'Sunday' THEN 24 ELSE 0 END)
-(Case When DATENAME(dw,NormalizedSRAssignedDate) = 'Saturday' THEN 24 ELSE 0 END)
When id Like 'CR%' Then DATEDIFF(hour,NormalizedCreatedDate,NormalizedCRAssignedDate)
-(DATEDIFF(wk,normalizedcreateddate,NormalizedCRAssignedDate)*48)
-((DATEDIFF(day,normalizedcreateddate,NormalizedCRAssignedDate)-(DATEDIFF(wk,normalizedcreateddate,NormalizedCRAssignedDate)*2))*14)
-(Case When DateName(dw,NormalizedCreatedDate) = 'Sunday' THEN 24 ELSE 0 END)
-(Case When DATENAME(dw,NormalizedCRAssignedDate) = 'Saturday' THEN 24 ELSE 0 END)
END),
IRAvgAssign = AVG(DATEDIFF(hour,NormalizedCreatedDate,NormalizedIRAssignedDate)
-(DATEDIFF(wk,normalizedcreateddate,NormalizedIRAssignedDate)*48)
-((DATEDIFF(day,normalizedcreateddate,NormalizedIRAssignedDate)-(DATEDIFF(wk,normalizedcreateddate,NormalizedIRAssignedDate)*2))*14)
-(Case When DateName(dw,NormalizedCreatedDate) = 'Sunday' THEN 24 ELSE 0 END)
-(Case When DATENAME(dw,NormalizedIRAssignedDate) = 'Saturday' THEN 24 ELSE 0 END)),
SRAvgAssign = AVG(DATEDIFF(hour,NormalizedCreatedDate,NormalizedSRAssignedDate)
-(DATEDIFF(wk,normalizedcreateddate,NormalizedSRAssignedDate)*48)
-((DATEDIFF(day,normalizedcreateddate,NormalizedSRAssignedDate)-(DATEDIFF(wk,normalizedcreateddate,NormalizedSRAssignedDate)*2))*14)
-(Case When DateName(dw,NormalizedCreatedDate) = 'Sunday' THEN 24 ELSE 0 END)
-(Case When DATENAME(dw,NormalizedSRAssignedDate) = 'Saturday' THEN 24 ELSE 0 END)),
CRAvgAssign = AVG(DATEDIFF(hour,NormalizedCreatedDate,NormalizedCRAssignedDate)
-(DATEDIFF(wk,normalizedcreateddate,NormalizedCRAssignedDate)*48)
-((DATEDIFF(day,normalizedcreateddate,NormalizedCRAssignedDate)-(DATEDIFF(wk,normalizedcreateddate,NormalizedCRAssignedDate)*2))*14)
-(Case When DateName(dw,NormalizedCreatedDate) = 'Sunday' THEN 24 ELSE 0 END)
-(Case When DATENAME(dw,NormalizedCRAssignedDate) = 'Saturday' THEN 24 ELSE 0 END))
FROM (
Select WI.id,
CASE
WHEN wi.CreatedDate < DATEADD(HOUR, 9, CAST(CAST(wi.CreatedDate AS DATE) AS DATETIME))
THEN DATEADD(HOUR, 9, CAST(CAST(wi.CreatedDate AS DATE) AS DATETIME))
ELSE wi.CreatedDate
END NormalizedCreatedDate,
CASE
WHEN IR.FirstAssignedDate !=NULL THEN CASE
WHEN IR.FirstAssignedDate > DATEADD(HOUR, 17, CAST(CAST(IR.FirstAssignedDate AS DATE) AS DATETIME))
THEN DATEADD(HOUR, 17, CAST(CAST(IR.FirstAssignedDate AS DATE) AS DATETIME))
ELSE IR.FirstAssignedDate END
ELSE CASE WHEN IR.ResolvedDate > DATEADD(HOUR, 17, CAST(CAST(IR.ResolvedDate AS DATE) AS DATETIME))
THEN DATEADD(HOUR, 17, CAST(CAST(IR.ResolvedDate AS DATE) AS DATETIME))
ELSE IR.ResolvedDate END
END NormalizedIRAssignedDate,
CASE
WHEN SR.FirstAssignedDate !=NULL THEN CASE
WHEN SR.FirstAssignedDate > DATEADD(HOUR, 17, CAST(CAST(SR.FirstAssignedDate AS DATE) AS DATETIME))
THEN DATEADD(HOUR, 17, CAST(CAST(SR.FirstAssignedDate AS DATE) AS DATETIME))
ELSE SR.FirstAssignedDate END
ELSE CASE WHEN SR.CompletedDate > DATEADD(HOUR, 17, CAST(CAST(SR.CompletedDate AS DATE) AS DATETIME))
THEN DATEADD(HOUR, 17, CAST(CAST(SR.CompletedDate AS DATE) AS DATETIME))
ELSE SR.CompletedDate END
END NormalizedSRAssignedDate,
CASE
WHEN CR.FirstAssignedDate !=NULL THEN CASE
WHEN CR.FirstAssignedDate > DATEADD(HOUR, 17, CAST(CAST(CR.FirstAssignedDate AS DATE) AS DATETIME))
THEN DATEADD(HOUR, 17, CAST(CAST(CR.FirstAssignedDate AS DATE) AS DATETIME))
ELSE CR.FirstAssignedDate END
ELSE CASE WHEN CR.ActualEndDate > DATEADD(HOUR, 17, CAST(CAST(CR.ActualEndDate AS DATE) AS DATETIME))
THEN DATEADD(HOUR, 17, CAST(CAST(CR.ActualEndDate AS DATE) AS DATETIME))
ELSE CR.ActualEndDate END
END NormalizedCRAssignedDate
from WorkItemDimvw WI
Left Outer Join IncidentDimvw IR
on WI.EntityDimKey=IR.EntityDimKey
Left Outer Join ServiceRequestDimvw SR
on WI.EntityDimKey=SR.EntityDimKey
Left Outer Join ChangeRequestDimvw CR
on WI.EntityDimKey=CR.EntityDimKey
Where (
(IR.ResolvedDate >= @StartDate AND IR.ResolvedDate < @EndDate)
OR (SR.CompletedDate >= @StartDate AND SR.CompletedDate < @EndDate)
OR (CR.ActualEndDate >= @StartDate AND CR.ActualEndDate < @EndDate)
)
) dataset
编辑 - 显然我们并没有排除下午5点之后的时间(在我的例子中它是8到6之间,因为这是我的客户想要的)所以我在计算中添加了每天删除14小时(除了周末)项目是开放的,它给了我我认为的确切数字
答案 1 :(得分:0)
这对我来说是一个有趣的问题。我对这个方法采取了一些措施:
CreatedDate
总是在FirstAssignedDate
SET DATEFIRST 7
(如果不同则更改工作日数字)CreatedDate
和FirstAssignedDate
这是我的方法,我确信它的效率非常低,但这是我的第一个想法:
SELECT
WIAvgAssign = AVG(
Case
When id Like 'IR%' Then DATEDIFF(hour,NormalizedCreatedDate,NormalizedIRAssignedDate)
When id Like 'SR%' Then DATEDIFF(hour,NormalizedCreatedDate,NormalizedSRAssignedDate)
When id Like 'SR%' Then DATEDIFF(hour,NormalizedCreatedDate,NormalizedCRAssignedDate)
END
),
IRAvgAssign = AVG(DATEDIFF(hour,NormalizedCreatedDate,NormalizedIRAssignedDate)),
SRAvgAssign = AVG(DATEDIFF(hour,NormalizedCreatedDate,NormalizedSRAssignedDate)),
CRAvgAssign = AVG(DATEDIFF(hour,NormalizedCreatedDate,NormalizedCRAssignedDate))
FROM (
Select WI.id,
CASE
WHEN wi.CreatedDate < DATEADD(HOUR, 9, CAST(CAST(wi.CreatedDate AS DATE) AS DATETIME))
THEN DATEADD(HOUR, 9, CAST(CAST(wi.CreatedDate AS DATE) AS DATETIME))
ELSE wi.CreatedDate
END NormalizedCreatedDate,
CASE
WHEN IR.FirstAssignedDate > DATEADD(HOUR, 17, CAST(CAST(IR.FirstAssignedDate AS DATE) AS DATETIME))
THEN DATEADD(HOUR, 17, CAST(CAST(IR.FirstAssignedDate AS DATE) AS DATETIME))
ELSE IR.FirstAssignedDate
END NormalizedIRAssignedDate,
CASE
WHEN SR.FirstAssignedDate > DATEADD(HOUR, 17, CAST(CAST(SR.FirstAssignedDate AS DATE) AS DATETIME))
THEN DATEADD(HOUR, 17, CAST(CAST(SR.FirstAssignedDate AS DATE) AS DATETIME))
ELSE SR.FirstAssignedDate
END NormalizedSRAssignedDate,
CASE
WHEN CR.FirstAssignedDate > DATEADD(HOUR, 17, CAST(CAST(CR.FirstAssignedDate AS DATE) AS DATETIME))
THEN DATEADD(HOUR, 17, CAST(CAST(CR.FirstAssignedDate AS DATE) AS DATETIME))
ELSE CR.FirstAssignedDate
END NormalizedCRAssignedDate
from WorkItemDimvw WI
Left Outer Join IncidentDimvw IR
on WI.EntityDimKey=IR.EntityDimKey
Left Outer Join ServiceRequestDimvw SR
on WI.EntityDimKey=SR.EntityDimKey
Left Outer Join ChangeRequestDimvw CR
on WI.EntityDimKey=CR.EntityDimKey
--AVOID SATURDAYS and SUNDAYS in result set
--Also assumes SET DATEFIRST 7
Where DATEPART(WEEKDAY,wi.CreatedDate) NOT IN (1,7)
AND DATEPART(WEEKDAY,IR.FirstAssignedDate) NOT IN (1,7)
AND DATEPART(WEEKDAY,SR.FirstAssignedDate) NOT IN (1,7)
AND DATEPART(WEEKDAY,CR.FirstAssignedDate) NOT IN (1,7)
AND(
(IR.ResolvedDate >= @StartDate AND IR.ResolvedDate < @EndDate)
OR (SR.CompletedDate >= @StartDate AND SR.CompletedDate < @EndDate)
OR (CR.ActualEndDate >= @StartDate AND CR.ActualEndDate < @EndDate)
)
) dataset
所以我基本上只检查CreatedDate
&lt;当天0900,如果是这样的话,将时间设置为0900,然后检查FirstAssignedDate
&gt;如果是这样的话,当天1700并将时间设置为1700。如果他们在周末,我也会过滤掉所有CreatedDate
和FirstAssignedDate
。
编辑:
我更新了我原来的帖子。我更改了日期检查以使用DATEADD
而不是构建字符串并尝试将字符串转换为DATETIME