【发布时间】:2015-11-23 11:28:02
【问题描述】:
我需要根据带有一些中等复杂连接的查询中的行值来获取不相关表中的记录计数。所有数据都位于单个 SQL 2012 数据库中的一台服务器上,位于多个不同的表中。
我正在根据审计记录一次重新创建一张工单的工单移动历史记录,并且需要计算由连接创建的行中的跨度的工作日。门票在区域之间移动(分配),并且有关于在任何一个区域应该多长时间的指南。门票可能会多次前往同一区域,每次重新开始计时。
我需要在工作日计算中考虑公司假期。在查看了几个在 SE 上计算工作日的解决方案后,我决定使用公司日历表 (dbo.UPMCCALENDARM1) 并计算跨度之间的日期。似乎是个好主意...
我不知道如何将行值用作日期计数查询的参数。
下面的查询具有带变量和交叉连接的工作解决方案,但它仅适用于硬编码日期,如果我尝试使用它不起作用的字段值,因为它们不是子查询的一部分,并且不能被束缚。
-- DV_im_Audit_ASSIGNMENT.Time 和 Detail.RESOLVED_TIME 之间
理论上,我可能会在子查询中使用这个完整的查询来获取日期计数,但这是我可以做到的尽可能短并且仍然可以获得干净的数据。对于按需报告来说,这是一个相当大的提升,这将是我的最后选择。因此,我想与 UPMCCALENDARM1 联系,因为每次出现 DV_im_Audit_ASSIGNMENT.Time 和 Detail.RESOLVED_TIME 都已列出。
可以吗?如果有怎么办?
declare @NonBus integer
set @NonBus = '0'
set @NonBus = (select Count(UPMCCALENDARM1.DATE) as NonBus
from dbo.UPMCCALENDARM1
where UPMC_BUSINESS_DAY = 'f'
and UPMCCALENDARM1.DATE
between '2015-08-01' and '2015-08-31'
-- between DV_im_Audit_ASSIGNMENT.Time and Detail.RESOLVED_TIME
)
select DV_im_Audit_ASSIGNMENT.Incident_ID
, DV_im_Audit_ASSIGNMENT.Old_ASSIGNMENT
, DV_im_Audit_ASSIGNMENT.New_ASSIGNMENT
, DV_im_Audit_ASSIGNMENT.Time as Assign_Time
, B.Time as Reassign_Time
, Detail.OPEN_TIME
, Cal.NonBus
, NonBus
, Detail.RESOLVED_TIME
, A.rownumA
, B.rownumB
from dbo.DV_im_Audit_ASSIGNMENT
--Get RownumA as a select join so I can work with it here, else get an invalid column name 'rownumA' error
left join(select Incident_ID
, Old_ASSIGNMENT
, New_ASSIGNMENT
, [Time]
, rownumA = ROW_NUMBER() OVER (ORDER BY DV_im_Audit_ASSIGNMENT.Incident_ID, DV_im_Audit_ASSIGNMENT.Time)
from dbo.DV_im_Audit_ASSIGNMENT
where Incident_ID = ?
) as A
on DV_im_Audit_ASSIGNMENT.Incident_ID = A.Incident_ID
and DV_im_Audit_ASSIGNMENT.New_ASSIGNMENT = A.New_ASSIGNMENT
and DV_im_Audit_ASSIGNMENT.Time = A.Time
--Get time assigned to next group, is problomatic when assigned to the same group multiple times.
left join(select Incident_ID
, Old_ASSIGNMENT
, New_ASSIGNMENT
, [Time]
, rownumB = ROW_NUMBER() OVER (ORDER BY DV_im_Audit_ASSIGNMENT.Incident_ID, DV_im_Audit_ASSIGNMENT.Time)
from dbo.DV_im_Audit_ASSIGNMENT
where Incident_ID = ?
) as B
on DV_im_Audit_ASSIGNMENT.Incident_ID = B.Incident_ID
and DV_im_Audit_ASSIGNMENT.New_ASSIGNMENT = B.Old_ASSIGNMENT
and DV_im_Audit_ASSIGNMENT.Time < B.Time
and rownumA = (B.rownumB - 1)
--Get current ticket info
left join (select Incident_ID
, OPEN_TIME
, RESOLVED_TIME
from dbo.DV_im_PROBSUMMARYM1_Detail
where Incident_ID = ?
) as Detail
on DV_im_Audit_ASSIGNMENT.Incident_ID = Detail.Incident_ID
--Count non-bussiness days. This section is in testing and does not use dataview as a source.
-- this gets the date count for one group of dates, need a different count for each row based on assign time.
cross join (Select Count(UPMCCALENDARM1.DATE) as NonBus
from dbo.UPMCCALENDARM1
where UPMC_BUSINESS_DAY = 'f'
and UPMCCALENDARM1.DATE
between '2015-08-01' and '2015-08-30'
-- between DV_im_Audit_ASSIGNMENT.Time and Detail.RESOLVED_TIME
) as Cal
--Get data for one ticket
where DV_im_Audit_ASSIGNMENT.Incident_ID = ?
ORDER BY DV_im_Audit_ASSIGNMENT.Incident_ID, DV_im_Audit_ASSIGNMENT.Time
仅供参考 - 我正在通过 BIRT 4.2 运行此 SQL,我相信很少有 SQL 项不会通过 BIRT
【问题讨论】:
-
只是为了确定:因为在数据样本中 Detail.RESOLVED_TIME 似乎是事件的解决日期(而不是每次重新分配的日期),它不应该类似于“DV_im_Audit_ASSIGNMENT.Time 之间”和重新分配时间'?在这种情况下,一个选项是通过过滤 Assign_time 和 Reassign_time(没有子查询)与 UPMCCALENDARM1 进行标准连接,然后在所有输出字段上应用“分组依据”以计算“非总线”计数。但是我认为最简单和最有效的方法是存储过程,如果它适用于您的上下文。
-
@Dominique 正确,这将是指标之一,有几个。我正在研究 Resolved time 指标,因为它有一些更长的跨度,当你有逻辑错误时,更长的跨度会导致更明显的错误。
-
@Dominique 谢谢。
标签: sql join sql-server-2012 birt