sql - 如何计算超过 17 周的工作时间
问题描述
我正在尝试计算有多少现场工程师在 17 周内工作超过 48 小时。(根据法律,您不能在 17 周内工作超过 48 小时)我设法为 1 名工程师运行查询,但是当我在没有工程师过滤器的情况下运行它时,我的查询非常慢。我需要计算工作时间超过 48 小时和少于 48 小时的工程师数量,然后计算每周平均工作时间。
注意:我在 SPICEMEISTER 和 SMARTMEISTER 上做一个联合,因为它们是我们的新旧数据库。
• 48 小时内有多少现场工程师工作 • 48 小时内有多少现场工程师工作 • 工程师每周平均工作时间是多少
SELECT DS_Date
,TechPersNo
FROM
(
SELECT DISTINCT
SMDS.EPL_DAT as DS_Date
,EN.pers_no as TechPersNo
FROM
[SpiceMeister].[FS_OTBE].[EngPayrollNumbers] EN
INNER JOIN
[SmartMeister].[Main].[PlusDailyKopf] SMDS
ON RIGHT(CAST(EN.[TechnicianID] AS CHAR(10)),5) = SMDS.PRPO_TECHNIKERNR
WHERE
SMDS.EPL_DAT >= '2017-01-01'
and
SMDS.EPL_DAT < '2018-03-01'
UNION ALL
SELECT DISTINCT
SPDS.DailySummaryDate as DS_Date
,EN.pers_no as TechPersNo
FROM
[SpiceMeister].[FS_OTBE].[EngPayrollNumbers] EN
INNER JOIN
[SpiceMeister].[FS_DS_BO].[DailySummaryHeader] SPDS
ON EN.TechnicianID = SPDS.TechnicianID
WHERE
SPDS.DailySummaryDate >= '2018-03-01'
) as Techa
where TechPersNo = 850009
) Tech
cross APPLY
快速的结果
解决方案
速度缓慢肯定是由于使用交叉应用和相关子查询。这将强制以每行为基础进行计算,并阻止 SQL Server 优化任何内容。
这似乎更像是一个“分组依据”查询,但我可以理解为什么你在复杂的累积计算中遇到了麻烦,因为你需要按人和日期输出,但平均值不涉及日期有问题,但日期范围在有问题的日期结束。
我首先要做的是进行一个通用查询来捕获两个数据集之间的基础数据。这就是我在下面的“dailySummaries”公用表表达式中所做的。然后我会将dailySummaries加入到员工匹配的自身并选择所需的日期范围。从那时起,我将按员工和日期分组,按日期范围汇总。
with
dailySummaries as (
select techPersNo = en.pers_no,
ds_date = smds.epl_dat,
dtDif = datediff(minute, smds.abfahrt_zeit, smds.rueck_zeit)
from smartMeister.main.plusDailyKopf
join smartMeister.main.plusDailyKopf smds
on right(cast(en.technicianid as char(10)),5) = smds.prpo_technikernr
where smds.epl_dat < '2018-03-01'
union all
select techPersNo = en.pers_no,
dailySummaryDate,
datediff(minute,
iif(spds.leaveHome < spds.workStart, spds.leaveHome, spds.workStart),
iif(spds.arrivehome > spds.workEnd, spds.arrivehome, spds.workEnd)
)
from spiceMeister.fs_ds_bo.dailySummaryHeader spds
join spiceMeister.fs_ds_bo.dailySummaryHeader spds
on en.TechnicianID = spds.TechnicianID
where spds.DailySummaryDate >= '2018-03-01'
)
select ds.ds_date,
ds.techPersNo,
AvgHr = convert(real, sum(dsPrev.dtDif)) / (60*17)
from dailySummaries ds
left join dailySummaries dsPrev
on ds.techPersNo = dsPrev.techPersNo
and dsPrev.ds_date between dateadd(day,-118, ds.ds_date) and ds.ds_date
where ds.ds_date >= '2017-01-01'
group by ds_date,
techPersNo
order by ds_date
我的翻译可能有一两处错误,但你明白了。
将来,发布一个更简单的示例。来自不同数据库的两个数据集的联合并不是您试图询问的问题的核心。许多日期过滤不是问题的核心。连接匹配逻辑中的特殊转换并不重要。这些事情掩盖了真正的问题。
推荐阅读
- java - Javax Transformer 在多线程服务中为空
- tensorflow - ssd_mobilenet_v1_coco 与 ssd_mobilenet_v1_quantized_coco
- python - 如何使用 SWIG 包装一个 C++ 函数,该函数使用对结构向量的引用作为要在 Python 中使用的输入和输出?
- r - tbl_df(hflights) 中的错误:找不到函数“tbl_df”
- python-3.x - 无法分配形状 (1482535, 67826) 和数据类型 int64 的数组
- r - 我在哪里可以找到这种带有 x、y 轴的圆形图的源代码?
- c - 如何在 CubeMX 中配置双代码引导模式
- c++ - 构造函数 SFINAE 和继承在 clang 中失败
- react-native - 如何在本机反应中旋转字体真棒图标?
- ios - 当应用程序在后台时如何在键盘前显示keyWindow?