2013-04-23 1 views
2

У меня есть SQL, как:оракул добавления, а затем в среднем с нулевым

select avg(decode(type, 'A', value, null) + decode(type, 'B', value, null)) from table; 

Проблема с этим некоторые из этих типов может быть нулевой, так что добавление часть приведет к нулевой, потому что добавление ничего нуль делает ноль. Таким образом, вы можете подумать, что я могу изменить декодирование от нуля до 0, но похоже, что avg() считает это частью его усреднения, но это не должно/я не хочу, чтобы он считался частью среднего.

В идеале добавление просто игнорирует нули и просто не пытается добавить их к остальным значениям.

Так скажем, мои цифры:

5 + 6 + 5 
3 + 2 + 1 
4 + null + 2 

Они всего 28, и я хотел бы разделить на 8 (игнорировать нуль), но если изменить нулевое значение 0 в декодировании, в СРЕДНЕМ затем разделится на 9, что не то, что я хочу.

ответ

0

Простое решение было бы вычислить среднее сами:

select 
    -- The sum of all values with type 'A' or 'B' 
    sum(decode(type, 'A', value, 'B', value, 0))/
    -- ... divided by the "count" of all values with type 'A' or 'B' 
    sum(decode(type, 'A', 1, 'B', 1, 0)) 
from table; 

A SQLFiddle example

Но путь AVG() работы, это, вероятно, будет достаточно, если вы только что удалили добавление и поместить все в a single DECODE()

select avg(decode(type, 'A', value, 'B', value, null)) from table 
0

Это сложнее сделать здесь сумму. Juste выводит значения с помощью CASE, и все готово.

SELECT AVG(
    CASE WHEN type = 'A' OR type = 'B' 
    THEN value 
    ELSE null 
    END 
) 
FROM table 
+0

Кажется, что я не получаю то же значение, что и исходный запрос, который я перерабатываю. Оригинал будет сам присоединяться к себе для каждого другого типа, тогда они будут avg (a.value + b.value + c.значение), но самосоединение убивает производительность. В основном все, что они пытались сделать, это поворот таблицы по типу, поэтому я использую декодирование для всех остальных столбцов, и она отлично работает, но это дополнение перед тем, как avg() дает мне проблемы. – user441521

+0

Редактировать сообщение своим полным запросом, потому что ему не хватает информации. –

+0

На самом деле это не так. Единственное, что мне не хватает, это столбец даты и столбец имен. Таблица - дата/имя/тип/значение, и я поворачиваю по типу и усредняет значения, но мне нужно суммировать их до их поворота. Предположим, что типы - это продукты, а ценности - это ежедневные цены. Затем скажите, что я хочу добавить все типы цитрусовых, а затем avg them. Это в основном идея. – user441521

1

Как написано, ваш код должен всегда возвращать null, так как, если первые decode возвращается value, то второй decode должен всегда возвращаться null. Я буду считать, что вы сделали ошибку в genericizing код и то, что вы на самом деле имел в виду следующее:.

avg(decode(type1, 'A', value1, null) + decode(type2, 'B', value2, null)) 

(Или, вместо type1, это может быть a.type Дело в том, что поля в два декодирует предназначено для отдельных полей)


в этом случае, я думаю, что easisest, что нужно сделать, это проверить на нули первым:

avg(case when type1 is null and type2 is null then null 
    else case type1 when 'A' then value1 else 0 end 
     + case type2 when 'B' then value2 else 0 end 
    end) 

(я повторно помещенный decode с case, потому что я считаю, что легче читать, но, в этом случае decode будет работать так же хорошо)

+0

Я думаю, что о OP вопрос. +1 для CASE, поскольку DECODE является специфичным для Oracle. –

+0

Что я имею в своем первоначальном посте, больше соответствует структуре таблицы, чем то, что вы говорите. Дата/Тип/значение. Я декодирую каждое значение другого типа для поворота таблицы, но мне нужно добавить 4 разных типа вместе, а затем их. – user441521

+0

Я перерабатываю запрос, сделанный кем-то другим. Для поворота они сами присоединялись к таблице для каждого другого типа, что сделало запрос очень медленным. У меня все остальные поля прекрасны, потому что они простые avg (decode (..)), но это поле 1 добавлено разными типами. – user441521

0

Логика здесь немного сложнее:.

select avg((case when type = 'A' then value else 0 end) + (case when type = 'B' then value else 0 end)) 
from table 
where type in ('A', 'B') 

В where оговорка гарантирует, что вы имеют по крайней мере один «А» или «В». Проблема возникает, когда у вас нет примеров «A» или «B».

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