2016-06-28 5 views
-2

Я рассчитываю коэффициент, основанный на Годе и Месяце за каждый год. Оба оператора CASE отображают правильные значения, которые необходимо разделить. Но по какой-то причине я получил 0 или -100Оператор CASE, деленный на другой оператор CASE, дает значение 0

;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

+0

Каков тип данных столбца 'Премиум'? –

+0

Int дивиденд на большее значение int даст нуль. Ввести либо числитель, либо знаменатель на что-то с десятичной цифрой –

+0

Тип данных - это деньги – Oleg

ответ

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/Premium или Premium/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) * 100 ИЛИ Premium/(-1 * 100)

Вы не сравниваете строки, которые вы сравниваете столбцов и в этом случае значение того же столбца равно двум различным значениям.

Возможно, вы имеете в виду одну сторону подразделения, которую нужно оценить, глядя на стол a вместо b?

Только зная, что я вижу в ваших запросах, оставьте свой cte as is и просто измените свой запрос на него следующим образом. Заметьте, что я изменил ваш 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 

Что она делает это самостоятельно присоединяется еще одну копию вашего КТР, но от 1 года меньше, чем s.yearnum Поскольку вы используете внешние связи он будет включать в себя все годы и т.д., так что если есть не совпадение вы необходимо обработать нулевое значение. После этого нет необходимости сравнивать любые даты, потому что вам гарантировано, что таблица a будет на 1 год выше, чем таблица b.

+0

b таблица представляет собой таблицу календаря. Я использую левое соединение для получения данных на все месяцы, даже если данных нет. Я добавил изображение с образцом данных – Oleg

+0

Олег вы сравниваете b.value = 2016 в числителе и b.value = b.2015 в знаменателе. Только 1 из этих условий будет истинным для каждой строки. Это означает, что вы всегда будете получать ELSE часть хотя бы одного из ваших заявлений. Посмотрите, что я говорю вам, это будет оценивать, к чему подразумевается ваше описание. Вам нужно работать над вашими сравнениями и, возможно, даже принять участие в этом году за год. – Matt

+0

Спасибо. Есть ли примеры, связанные с моей проблемой? – Oleg

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 

Matching на месяц и год, но в случае заявления вы используете Numerator и denominator разных лет.

Оператор Case делает точно противоположное тому, что делает ваше условие соединения. Следовательно, оператор case никогда не оценивает значение true, и вы получаете все NULLS.

+0

Теперь я получил -100.0000000000 – Oleg

+0

, если бы вы могли добавить некоторые примеры данных на ваш вопрос, это поможет увидеть, где вы идет не так. –

+0

(значение января 2016 года/значение в январе 2015 года) - 1 – Oleg

Смежные вопросы