CASE语句除以另一个CASE语句,给出值0

时间:2016-06-28 22:10:15

标签: sql tsql case

我根据每年的年份和月份计算比率。两个CASE语句都带来了正确的值,需要进行划分。但由于某种原因,我得到0或-100

;WITH cte_yoyComparison
AS
        (
SELECT  Year(EffectiveDate) AS EffectiveYear,
        Month(EffectiveDate) AS EffectiveMonth,
        SUM(Premium) as Premium 
FROM    Test_Plaza_ProductionReport 
WHERE YEAR(EffectiveDate) <> 2017
GROUP BY      Year(EffectiveDate),
                Month(EffectiveDate)            
            )
SELECT *, b.YearNum,b.MonthNum,

            ((case when b.YearNum=2016 and b.MonthNum=1 THEN Premium   end ))   /(case when b.YearNum = 2015 and b.MonthNum = 1 THEN Premium end)  as Ratio,
            ((((case when b.YearNum=2015 and b.MonthNum=1 THEN Premium   else 0 end))   /NULLIF((case when b.YearNum = 2016 and b.MonthNum = 1 THEN Premium   else 0 end),0))-1)*100 as Ratio1,
            case when b.YearNum=2015 and b.MonthNum=1 THEN Premium  else 0 end as CorrectValue,
            case when b.YearNum = 2016 and b.MonthNum = 1 THEN Premium else 0 end as CorrectValue1
 FROM tblCalendar b  
LEFT JOIN cte_yoyComparison a ON b.MonthNum=a.EffectiveMonth AND b.YearNum=a.EffectiveYear
WHERE b.YearNum<>2017
Order BY EffectiveYear desc,EffectiveMonth

enter image description here

2 个答案:

答案 0 :(得分:0)

我已将* 1.00添加到您的分子中,这实际上会导致十进制转换。

;WITH cte_yoyComparison
AS
        (
SELECT  Year(EffectiveDate) AS EffectiveYear,
        Month(EffectiveDate) AS EffectiveMonth,
        SUM(Premium) as Premium 
FROM    Test_Plaza_ProductionReport 
WHERE YEAR(EffectiveDate) <> 2017
GROUP BY      Year(EffectiveDate),
                Month(EffectiveDate)            
            )
SELECT *, b.YearNum,b.MonthNum,

            ((case when b.YearNum=2016 and b.MonthNum=1 THEN Premium * 1.00  end ))   
                     /(case when b.YearNum = 2015 and b.MonthNum = 1 THEN Premium * 1.00 end)  as Ratio,
            ((((case when b.YearNum=2015 and b.MonthNum=1 THEN Premium * 1.00  else 0 * 1.00 end))   
                      /NULLIF((case when b.YearNum = 2016 and b.MonthNum = 1 THEN Premium * 1.00  else 0 * 1.00 end),0))-1)*100 as Ratio1,
            case when b.YearNum=2015 and b.MonthNum=1 THEN Premium * 1.00  else 0 * 1.00 end as CorrectValue,
            case when b.YearNum = 2016 and b.MonthNum = 1 THEN Premium * 1.00 else 0 * 1.00 end as CorrectValue1
 FROM tblCalendar b  
LEFT JOIN cte_yoyComparison a ON b.MonthNum=a.EffectiveMonth AND b.YearNum=a.EffectiveYear
WHERE b.YearNum<>2017
Order BY EffectiveYear desc,EffectiveMonth

现在查看您的数据,很明显您为什么没有获得所需的结果集。你的加入条件说

  b.MonthNum=a.EffectiveMonth AND b.YearNum=a.EffectiveYear

在月份和年份匹配,但在案例陈述中,您使用的是不同年份的Numeratordenominator

您的Case语句与您的连接条件正好相反,因此case语句永远不会计算为true,并且您将获得所有NULLS。

答案 1 :(得分:0)

看起来你想要比较2行而不是两列,但实际上是将1列与2个值进行比较。

((case when b.YearNum=2016 and b.MonthNum=1 THEN Premium   end ))   /(case when b.YearNum = 2015 and b.MonthNum = 1 THEN Premium end)  as Ratio,

将始终评估为NULL / PremiumPremium / Null,因为b.YearNum不能是同一行中的2个值

((((case when b.YearNum=2015 and b.MonthNum=1 THEN Premium   else 0 end))   /NULLIF((case when b.YearNum = 2016 and b.MonthNum = 1 THEN Premium   else 0 end),0))-1)*100 as Ratio1,

将始终评估为0 / (Premium -1) * 100Premium / (-1 * 100)

您不是要比较列的行,在这种情况下,将同一列的值与2个不同的值进行比较。

您是否可以通过查看表a而不是b来评估该部门的一方?

只知道我在查询中可以看到的内容,请按原样保留您的cte,然后将查询从中更改为以下内容。注意我确实将你的tblCalendar从a更改为c它更多,因为对我来说,日历以c开头。

SELECT *,
    ISNULL(a.Premium,0) / ISNULL(b.Premium,1) AS Ratio
FROM tblCalendar c  
    LEFT JOIN cte_yoyComparison a
    ON c.MonthNum=a.EffectiveMonth
    AND c.YearNum=a.EffectiveYear
    LEFT JOIN cte_yoyComparison b
    ON c.MonthNum=b.EffectiveMonth
    AND c.YearNum - 1 = b.EffectiveYear
WHERE
    c.YearNum<>2017
ORDER BY
    c.YearNum DESC
    ,c.MonthNum

它的作用是自我加入你的cte的另一个副本,但比s.yearnum少1年因为你使用外连接它将包括所有年份等所以如果没有匹配你需要处理空值。之后,无需比较任何日期,因为您可以保证表格a比表格b更新1年。