SQL Server:通过运算符测量实时效率

问题描述 投票:0回答:1

我一直在研究一些SQL代码以实时测量某些生产数据的效率。快速背景介绍:

操作员将输入特定子装配体的数据。该数据如下所示:

ID                      PO      W/S     Status      Operator            TotalTime   Date 
60129515_2000_6_S025    107294  S025    Completed   A                   38          05/08/2020
60129515_2000_7_S025    107294  S025    Completed   A                   46          05/08/2020
60129515_2000_8_S025    107294  S025    Completed   A                   55          05/08/2020
60129515_2025_6_S020    107295  S020    Completed   B                   58          05/08/2020
60129515_2025_7_S020    107295  S020    Completed   B                   47          05/08/2020
60129515_2025_8_S020    107295  S020    Completed   B                   45          05/08/2020
60129515_2000_1_S090    107294  S090    Completed   C                   33          05/08/2020
60129515_2000_2_S090    107294  S090    Completed   C                   34          05/08/2020
60129515_2000_3_S090    107294  S090    Completed   C                   21          05/08/2020

相关的列是OperatorTotalTimeDate(请注意,日期存储为varchar(50),因为这样可以更好地与Microsoft PowerApps配合使用)。

我需要做的是:

  • 汇总由运营商分组的“ TotalTime”之和
  • 根据以下条件计算经过的时间:
    • 如果在上午7点至下午4点之间,请计算自当天上午7点起经过的时间
    • 如果在下午4点之后,返回当日上午7点至下午4点之间的总时间
  • 将SUM(TotalTime)除以TimeElapsed(也就是第一个列表项/第二个列表项),以便大致估算出工作时间与一天中所经过的小时数。

此计算将在每次查询运行时更改。这将允许拉出此查询的Microsoft PowerApp实时刷新效率度量。我已经刺了一下-见下文:

SELECT
    md.Operator,
    CASE 
       WHEN DATEADD(HOUR, -5, GETUTCDATE()) > CONVERT(DATETIME, CONVERT(DATE, DATEADD(HOUR, -5, GETUTCDATE()))) + '7:00' AND GETDATE() < CONVERT(DATETIME, CONVERT(DATE, DATEADD(HOUR, -5, GETUTCDATE()))) + '15:45' 
          THEN (SUM(isNull(md.TotalTime, 0)) + SUM(isNull(md.DelTime, 0))) * 1.0 / DATEDIFF(MINUTE, CONVERT(DATETIME, CONVERT(DATE, DATEADD(HOUR, -5, GETUTCDATE()))) + '7:00' , DATEADD(HOUR, -5, GETUTCDATE())) * 100.0
          ELSE (SUM(isNull(md.TotalTime, 0)) + SUM(isNull(md.DelTime, 0))) / 420 * 100.0
    END AS OpEfficiency
FROM 
    [Master Data] AS md
WHERE 
    md.[Date] = CONVERT(varchar(50), DATEADD(HOUR, -5, GETUTCDATE()), 101)
GROUP BY 
    md.Operator

DelTime是有关延迟时间的另一列。我还将转换为UTC时间,以避免在转移到PowerApps时出现任何时区问题。

但是,这效率极低。我假设这是因为Date需要每一次转换为日期时间。如果我的计算列已经转换了日期,效果会更好吗?还是有更好的方法来计算自某个时间以来经过的时间?

谢谢。

sql-server tsql time ssms powerapps
1个回答
0
投票

您可以采取一些措施来大大提高效率。首先,您要确保SQL在选择行时可以进行简单的比较,因此,从[Date]字段不是日期的字符串开始,计算与日期匹配的字符串。

第二,提前计算您的班次分钟数(完整班次为540分钟,或者在上午7点精确缩小为0,因此您不必在每一行中都计算分钟数。

第三,在对运算符求和时,请在分钟数上使用一个简单的总和,然后根据该总和以及您预先计算的班次到目前为止的分钟来计算效率。

[一个注释-在我的示例中,我正在铸造分钟,直到FLOAT为止,也许不是最好的类型,但是比其他十进制类型(如DECIMAL(18,6))或其他类型更清晰。选择可以显示所需比例的东西。

我的示例使用通用表表达式生成该日期字符串和到目前为止的分钟数FLOAT,这很好,因为它适合直接查询,视图,函数或存储过程,但是如果您愿意,可以使用DECLARE变量。

通过对预先计算出的TargetDate字符串使用[Date]字符串上的INNER JOIN进行过滤,我确保在对任何数据进行任何数学运算之前,将数据集缩减为最少的记录。您肯定会想要INDEX [Date],以便在表格填满时保持此速度。

所有这些都应该提供一个非常快速的查询,祝您好运

with cteNow as ( --Calculate once, up front - date as string, minutes elapsed as FLOAT (or any non-integer)
    SELECT CASE WHEN 60*DATEPART(HOUR, GETUTCDATE())+DATEPART(MINUTE, GETUTCDATE()) > 60*21 
                    --4PM in UTC-5, expressed in minutes
            THEN CONVERT(float,(16-7)*60) --minutes in (4 PM-7 AM) * 60 minutes/hour
        ELSE --Assume nobody is running this at 6 AM, so ELSE = between 7 and 4
            CONVERT(float,60*DATEPART(HOUR, GETUTCDATE()) + DATEPART(MINUTE, GETUTCDATE()) - ((7+5)*60))
             --Minutes since midnight minus minutes from midnight to 7 AM, shifted by 
             --UTS offset of 5 hours
        END as MinutesToday --Minutes in today's shift so far
        , FORMAT(DATEADD(HOUR,-5,GETUTCDATE()),'MM/dd/yyyy') as TargetDate --Date to search for
            --as a string so no conversion in every row comparison. Also, index [Date] column
)
SELECT md.Operator, SUM(md.TotalTime) as TotalTime, SUM(md.TotalTime) / MinutesToday as Efficiency
FROM [Master Data] AS md INNER JOIN cteNow as N on N.TargetDate = md.[Date]
GROUP BY md.Operator, MinutesToday

顺便说一句,您没有为午餐或上午7点之前的跑步津贴,所以我也忽略了这些。我认为都可以在cteNOW中解决这两个问题,而不会增加太多复杂性。

© www.soinside.com 2019 - 2024. All rights reserved.