在SQL请求中,我计算了一些东西。这个微积分需要一个表(DurationsLog
)不为空(表必须包含行)。
所以我正在尝试处理这个表为空的情况。
所以我尝试在select中使用CASE来处理它但它不起作用(当DurationsLog
为空时得到0行)。
以下是请求:
SELECT
o.Maint,
CASE
WHEN EXISTS(SELECT * FROM DurationsLog)
THEN DATEADD(day, (p.CycleDuration - (c.TotalRotationCounter - o.LastActionCounter)) / AVG(d.RotationDuration), GetDate())
ELSE 'CALCUL IMPOSSIBLE'
END AS CalculProchaineDate
FROM
dbo.Operations o
INNER JOIN
dbo.Periods As p ON o.PeriodId = p.Id,
dbo.Counters c,
dbo.DurationsLog d
WHERE
p.CycleDuration>0
GROUP BY
o.Maint, p.CycleDuration, c.TotalRotationCounter, o.LastActionCounter
注意:DurationsLog
没有加入另一个表
NB bis:当DurationsLog
包含行时,它正常工作
注意3:SQL系统是Microsoft SQL Server 2008
编辑:好像我没有很好地解释我的问题,我会详细介绍一下:
dbo.Operations表包含有关维护操作的信息。它的主键是“Maint”,它在dbo.Periods表中包含一个外键“PeriodId”。
dbo.Periods表包含一个Id作为主键和一个用于微积分的字段“CycleDuration”
dbo.Counters没有主键。它包含机器使用的总计数器(它旋转了多少小时,产生......),这个表总是只包含一行
dbo.DurationsLog包含一个主键,它是一个日期。该表存储了我们的机器今天旋转和生产的时间。所以这个表包含一行/天
来自Periods的“CycleDuration”存储两次操作之间的时间(以小时为单位)(例如:我们需要每4000小时清理x,CycleDuration将为4000)
我们在上次执行此操作时存储在Operations表中。所以我估计下一次操作什么时候需要执行。
这就是我计算的原因:CycleDuration - (我上次执行操作的计数器)/每天的平均持续时间。有了这个,我可以估计下一次行动何时进行。
答案 0 :(得分:0)
原因是,当DurationsLog
表为空时,INNER JOIN将始终为空
正是在这里:
INNER JOIN
dbo.Periods As p ON o.PeriodId = p.Id,
dbo.Counters c,
dbo.DurationsLog d
表Counters
,DurationsLog
和查询的其余部分之间没有连接条件。
解决方案是预先计算必要的值,而不是自己加入表格:
declare @AvgDuration float;
select
@AvgDuration = AVG( d.RotationDuration )
from dbo.DurationsLog d;
declare @TotalCounter int;
select
@TotalCounter = c.TotalRotationCounter
from dbo.Counters;
SELECT
o.Maint,
CASE
WHEN @AvgDuration IS NOT NULL
THEN DATEADD(day, (p.CycleDuration -
(@TotalCounter - o.LastActionCounter))
/ @AvgDuration, GetDate())
ELSE 'CALCUL IMPOSSIBLE'
END AS CalculProchaineDate
FROM
dbo.Operations o
INNER JOIN
dbo.Periods As p ON o.PeriodId = p.Id
WHERE
p.CycleDuration>0
GROUP BY
o.Maint, p.CycleDuration, o.LastActionCounter;