2017-05-26 46 views
1

我正在使用SQL Server 2008.我正在尝试构建一个T-SQL查询以基于来自多个表的数据计算一些性能指标。不幸的是,我被困在其中一个计算上,无法弄清楚什么是错误的。我将不胜感激任何帮助:在T-SQL连接查询中乘以列

  1. 的计算需要产生的总(从表ShiftHourCounts),总拆车件(从表ShiftReportScrap),总停机时间(从Downtime查询)

  2. 我试图在查询中添加每个操作/计算主要用于我自己的教育/故障排除

  3. 我不明白为什么列Q返回零。 Q = Tok/Tp,查询正确返回并单独计算Tok和Tp。在下面的示例中,Q应该= 0.994

  4. 查询当前返回除Q,A,P和OEE以外的所有内容的正确值。 Q,A,P,和OEE总是返回零

目前查询:

--OEE= A*P*Q (this is the final desired result/ calculation) 
--A= (Planned run time - Unplanned Down Time)/Planned run time 
--A= (Prt - Dtu)/Prt 
--Prt= Maximum Available Time - Planned Down Time 
--Prt= Mat=DTp 
--Effective production time= Planned run time - Unplanned Down Time 
--Ept=Prt-DTu 
--P= (BDT*total number of produced parts)/Effective production time 
--P= (BDT*Tp)/Ept 
--Q= Total number of OK parts/Total number of produced parts 
--Q= Tok/Tp 

select 
    sm.SR_ID, sm.SR_PartID, sm.SR_StartTime, 
    isnull(sm.SR_EndTime,GETDATE()) AS EndTime, 
    isnull(sm.SR_BDT,1) AS BDT, 
    DATEDIFF(n, sm.SR_StartTime, isnull(sm.SR_EndTime, GETDATE())) AS Prt, 
    isnull(p.TotalProduced,0) AS Tp, 
    isnull(s.Scrap,0) AS Scrap, 
    (isnull(p.TotalProduced, 0) - isnull(s.Scrap, 0)) AS Tok, 
    isnull(dt.DownTimeDuration, 0) AS DTu, 
    ((isnull(p.TotalProduced, 0) - isnull(s.Scrap, 0))/isnull(p.TotalProduced, 0)) AS Q, --Q= Tok/Tp 
    ((DATEDIFF(n, sm.SR_StartTime, isnull(sm.SR_EndTime, GETDATE())) - isnull(dt.DownTimeDuration, 0))/DATEDIFF(n, sm.SR_StartTime, isnull(sm.SR_EndTime, GETDATE()))) AS A, 
    ((isnull(sm.SR_BDT, 1) * isnull(p.TotalProduced, 0))/(DATEDIFF(n, sm.SR_StartTime, isnull(sm.SR_EndTime, GETDATE())) - isnull(dt.DownTimeDuration, 0))) AS P, 
    (((isnull(p.TotalProduced, 0) - isnull(s.Scrap, 0))/isnull(p.TotalProduced, 0)) * ((DATEDIFF(n, sm.SR_StartTime, isnull(sm.SR_EndTime, GETDATE())) - isnull(dt.DownTimeDuration, 0))/DATEDIFF(n, sm.SR_StartTime, isnull(sm.SR_EndTime, GETDATE())))*((isnull(sm.SR_BDT,1)*isnull(p.TotalProduced,0))/(DATEDIFF(n,sm.SR_StartTime,isnull(sm.SR_EndTime,GETDATE()))-isnull(dt.DownTimeDuration,0)))) AS OEE 
FROM 
    ShiftReportMaster sm 
LEFT JOIN 
    (SELECT 
     SH_ShiftID, Sum(SH_Produced) AS TotalProduced 
    FROM 
     ShiftHourCounts 
    GROUP BY 
     SH_ShiftID) p ON (p.SH_ShiftID = sm.SR_ID) 
LEFT JOIN 
    (SELECT 
     SRS_SR_ID, SRS_PartID, Sum(SRS_Scraped) AS Scrap 
    FROM 
     ShiftReportScrap 
    GROUP BY 
     SRS_SR_ID, SRS_PartID) s ON (s.SRS_SR_ID = sm.SR_ID) 
            AND (s.SRS_PartID = sm.SR_PartID) 
LEFT JOIN 
    (SELECT 
     srd.DTR_SRID, [Downtime reasons].DT_Planned, 
     Sum(srd.DTR_DownTimeDuration) AS DownTimeDuration 
    FROM 
     ShiftReportDowntime srd 
    LEFT JOIN 
     [Downtime reasons] ON srd.DTR_Reason = [Downtime reasons].DT_ID 
    GROUP BY 
     srd.DTR_SRID, [Downtime reasons].DT_Planned 
    HAVING 
     ((([Downtime reasons].DT_Planned) = 0))) dt ON (dt.DTR_SRID = sm.SR_ID) 
WHERE 
    sm.SR_ID = 3689; 

sample data and result

回答

1

从整数除法最有可能的。试试这个:

((isnull(p.TotalProduced+.0,0.0)-isnull(s.Scrap+.0,0.0)) 
/nullif(p.TotalProduced,0)) AS Q, --Q= Tok/Tp 

添加.0或乘1.0整数implictly转换成decimal类型。

划分整数将返回一个整数类型,如果该值小于1它将返回0,因为它截断而不是四舍五入或使用其他逻辑来返回整数。

+1

我在想同样的事情,但除数中的ISNULL在这里令人难以置信的可怕。如果p.TotalProduced为null,则会导致被零除错误。 –

+0

@SeanLange确实如此。我已经将它从原始代码改为在'p.TotalProduced'为0的情况下返回'null'而不是'0',以进一步避免被零除问题。 – SqlZim

+0

做了诀窍 - 谢谢你们俩!另外,还要感谢0分区的分区。 – argent65