我目前遇到的问题是除以零 - 我试图实施CASE
只是将划分的数字标记为" 1"但是,我仍然得到错误 - 我猜我在这里遗漏了什么?只是不确定是什么......
SELECT
CASE WHEN c.PageCount IS NULL OR c.PageCount=0 THEN 1 ELSE c.PageCount END as [PageCount],
cast(c.PageCount / CASE WHEN DATEDIFF(mi, ev.EventCreateDate, ev.EventCompletionDate) IS NULL OR DATEDIFF(mi, ev.EventCreateDate, ev.EventCompletionDate) = 0 THEN 1 ELSE DATEDIFF(mi, ev.EventCreateDate, ev.EventCompletionDate)END as decimal(5,2)) as PagesPerMinute,
CASE
WHEN DATEDIFF(mi, ev.EventCreateDate, ev.EventCompletionDate) >= 30 AND CAST(DATEDIFF(mi, ev.EventCreateDate, ev.EventCompletionDate) AS FLOAT)/CAST([PageCount] AS FLOAT) >= 1 THEN
CASE WHEN CAST([PageCount] AS FLOAT) * 0.5 /*Half minute*/ > 45 /*minutes*/ THEN 45 ELSE CAST([PageCount] AS FLOAT) * 0.5 /*Half minute*/ END
WHEN DATEDIFF(mi, ev.EventCreateDate, ev.EventCompletionDate) >= 60 AND CAST(DATEDIFF(mi, ev.EventCreateDate, ev.EventCompletionDate) AS FLOAT)/CAST([PageCount] AS FLOAT) < 1 /* 1 minute/page */ THEN 60
ELSE
DATEDIFF(mi, ev.EventCreateDate, ev.EventCompletionDate)
END [MinutesPaid]
FROM
tbl_Charts c
left outer join (select cd.ChartId, count(*) as CodesFound from tbl_ChartCodes cd group by cd.ChartId) cd on cd.ChartId = c.ChartId,
tbl_WFChartEvents ev,
tbl_Users u,
(select evar.ChartId, evar.ActionUserId, ar.ResultDescription, evar.ActionRemark, evar.ActionDate
from tbl_WFChartEventActions evar, tbl_WFChartEventActionResults ar
where evar.EventId = 201
and evar.ActionResultId = ar.ResultID and evar.EventId = ar.EventID
and evar.ActionTypeId = ar.ActionTypeID
and evar.EventId = 201) arr
WHERE
c.ChartId = ev.ChartId
and ev.EventId = 201
and ev.EventCreateUserId = u.UserId
and arr.ActionUserId = u.UserId
and arr.ChartId = c.ChartId
order by ev.EventCreateDate
答案 0 :(得分:1)
为了便于分割公式的可读性/可维护性,请使用NULLIF(x,0)
包装每个除数。
这比使用case语句检查零并确保除数与case谓词相同更容易。在任何地方,您都会看到/ [...]
,将其设为/ NULLIF( [...] ,0)
而不是:
cast(
c.PageCount / CASE
WHEN (DATEDIFF(mi, ev.EventCreateDate, ev.EventCompletionDate) IS NULL
OR DATEDIFF(mi, ev.EventCreateDate, ev.EventCompletionDate) = 0
)
THEN 1
ELSE DATEDIFF(mi, ev.EventCreateDate, ev.EventCompletionDate)
END
as decimal(5,2)
) as PagesPerMinute,
这样做:
cast(
coalesce(
c.PageCount / NULLIF(DATEDIFF(mi, ev.EventCreateDate, ev.EventCompletionDate), 0)
,c.PageCount --Return this value if preceding is null or div_by_zero
)
as as decimal(5,2)
) as PagesPerMinute
答案 1 :(得分:0)
我知道所有的sql,你不能在select中使用别名列。通过将c.PageCount别名化为[PageCount],我相信您仍在使用原始的c.PageCount而不使用表别名。要测试它,只需将[PageCount]更改为[PageCount2]。我怀疑你会收到一个错误,它无法识别列名。
这只会“显示”才能生效,因为您重复使用了结果中已有的唯一列名称。
我的意思是采用这种情况并用它替换[PageCount]。
CASE WHEN c.PageCount IS NULL OR c.PageCount=0 THEN 1 ELSE c.PageCount END
像这样
CASE
WHEN DATEDIFF(mi, ev.EventCreateDate, ev.EventCompletionDate) >= 30 AND CAST(DATEDIFF(mi, ev.EventCreateDate, ev.EventCompletionDate) AS FLOAT)/CAST(CASE WHEN c.PageCount IS NULL OR c.PageCount=0 THEN 1 ELSE c.PageCount END AS FLOAT) >= 1 THEN
CASE WHEN CAST([PageCount] AS FLOAT) * 0.5 /*Half minute*/ > 45 /*minutes*/ THEN 45 ELSE CAST([PageCount] AS FLOAT) * 0.5 /*Half minute*/ END
WHEN DATEDIFF(mi, ev.EventCreateDate, ev.EventCompletionDate) >= 60 AND CAST(DATEDIFF(mi, ev.EventCreateDate, ev.EventCompletionDate) AS FLOAT)/CAST(CASE WHEN c.PageCount IS NULL OR c.PageCount=0 THEN 1 ELSE c.PageCount END AS FLOAT) < 1 /* 1 minute/page */ THEN 60
ELSE
DATEDIFF(mi, ev.EventCreateDate, ev.EventCompletionDate)
END [MinutesPaid]
答案 2 :(得分:0)
我认为您的问题出在case
声明中:
CASE WHEN DATEDIFF(mi, ev.EventCreateDate, ev.EventCompletionDate) >= 30 AND
CAST(DATEDIFF(mi, ev.EventCreateDate, ev.EventCompletionDate) AS FLOAT)/CAST([PageCount] AS FLOAT) >= 1
THEN (CASE WHEN CAST([PageCount] AS FLOAT) * 0.5 /*Half minute*/ > 45 /*minutes*/
THEN 45 ELSE CAST([PageCount] AS FLOAT) * 0.5 /*Half minute*/
END)
WHEN DATEDIFF(mi, ev.EventCreateDate, ev.EventCompletionDate) >= 60 AND CAST(DATEDIFF(mi, ev.EventCreateDate, ev.EventCompletionDate) AS FLOAT)/CAST([PageCount] AS FLOAT) < 1 /* 1 minute/page */
THEN 60
ELSE DATEDIFF(mi, ev.EventCreateDate, ev.EventCompletionDate)
END AS [MinutesPaid]
第一个when
语句有一个除法。只需将其改为:
CASE WHEN DATEDIFF(mi, ev.EventCreateDate, ev.EventCompletionDate) >= 30 AND
CAST([PageCount] AS FLOAT) > 0 AND
CAST(DATEDIFF(mi, ev.EventCreateDate, ev.EventCompletionDate) AS FLOAT) >= CAST([PageCount] AS FLOAT)
THEN (CASE WHEN CAST([PageCount] AS FLOAT) * 0.5 /*Half minute*/ > 45 /*minutes*/
THEN 45 ELSE CAST([PageCount] AS FLOAT) * 0.5 /*Half minute*/
END)
WHEN DATEDIFF(mi, ev.EventCreateDate, ev.EventCompletionDate) >= 60 AND CAST(DATEDIFF(mi, ev.EventCreateDate, ev.EventCompletionDate) AS FLOAT)/CAST([PageCount] AS FLOAT) < 1 /* 1 minute/page */
THEN 60
ELSE DATEDIFF(mi, ev.EventCreateDate, ev.EventCompletionDate)
END AS [MinutesPaid]
我通过简单的比较删除了除法,并且保证该值不为0.