SQL Условное агрегирование
Я использую Oracle.
Наличие таблицы как:
Year Type Value
2011 1 500
2011 2 550
2011 3 600
...
...
2012 1 600
2012 2 750
2012 3 930
Мне нужно было вычесть все значения из разных типов, сгруппированных по годам. Операция будет:
На 2011 год -> 1-2-3 (500-550-600)
На 2012 год -> 1-2-3 (600-750-930)
За...
Результат должен быть:
Year Value
2011 -650
2012 -1080
... ...
Я не мог этого сделать, но здесь при переполнении стека этот запрос был предложен, и он работал:
select sum(case when type = 1 then value else - value end) as value
from table t
group by year;
Но сейчас у меня другая ситуация. Мне нужно сделать то же самое, но не 1-2-3-4-5-... Но 1+2-3-4-5-6....
К этому я попробовал это оба запроса, без успеха:
select sum(case when type = 1 then value when type = 2 then value else - value end) as value
from table t
group by year;
Это привело к тому, что второе значение удвоилось.
select sum(case when type = 1 then value else - value end)+case when type = 2 then value as value
from table t
group by year;
Это привело к правильному значению типа 2, но, поскольку этот тип 2 встречается только в некоторые годы, другие годы отображаются как нулевые. Таким образом, окончательный расчет верен для типа 2 (в каких годах), но для каждого другого года, для каждого типа 2 не существует, он возвращает ноль.
Мне просто не удается заставить этот запрос работать. Любая идея будет принята с благодарностью! Спасибо
3 ответа
Определение того, следует ли считать число положительным или отрицательным, должно происходить внутри вашей агрегации SUM()
, Так:
select sum(case when type = 1 OR type = 2 then value else - value end)
from table t
group by year;
Поскольку 1 и 2 положительны в вашей формуле 1+2-3-4-5-6... (подразумевается, что 1 означает положительное значение), вам необходимо OR, чтобы убедиться, что оба положительны, а все остальное отрицательно. Тогда он будет суммирован и ваш золотой.
Для полноты картины два альтернативных решения:
select sum(case when type in (1, 2) then value else -value end)
from t
group by year;
Или, используя простое выражение case:
select sum(case type
when 1 then value
when 2 then value
else -value
end)
from t
group by year;
Короткая версия с sign
используемый:
select year, sum(sign(-type+2.5)*value) from table t group by year