Подсчет всех других типов, кроме текущего

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

Так, например, для 4 типов каждый столбец в результирующей таблице будет содержать среднее значение всех остальных трех значений типа, мне нужно исключить строки текущего типа.

Например, если бы мне нужно было вычислить среднее значение каждого типа для себя, запрос выглядел бы так:

SELECT

SUM(some value) / COUNT(TYPE)

FROM TEMPTABLE
GROUP BY TYPE

Теперь я пытаюсь вычислить общее среднее значение остальных трех. Спасибо.


person Halo    schedule 23.07.2010    source источник
comment
Вы уверены, что имеете в виду столбцы, а не строки? Вы можете опубликовать структуру таблицы?   -  person    schedule 23.07.2010


Ответы (5)


Вы можете выполнить один запрос, чтобы получить разные типы, и LEFT JOIN одну и ту же таблицу, проверив неравенство типов:

SELECT t1.type,
       SUM(t2.some_value) / COUNT(t2.type)
FROM ( SELECT DISTINCT type FROM temptable ) t1
LEFT JOIN temptable t2 ON ( t1.type <> t2.type )
GROUP BY t1.type

Поскольку вам нужно только среднее значение, вы можете заменить строку

FROM ( SELECT DISTINCT type FROM temptable ) t1

by

FROM temptable t1

но первое решение может работать лучше, так как количество строк уменьшается раньше.

person Peter Lang    schedule 23.07.2010
comment
спасибо, я думаю, мне нужно написать что-то вроде этого как вложенный запрос, потому что эта часть является только членом гигантского SELECT. поэтому я не могу использовать FROM или WHERE напрямую - person Halo; 23.07.2010
comment
Не должно быть причин, по которым ответ Питера не может работать как под-/вложенный запрос, не так ли? (Моя Sybase заржавела) - person Tobiasopdenbrouw; 23.07.2010
comment
ну, я вычел текущее значение из суммы и разделил на (COUNT -1). Я не проверял ваше решение, но оно кажется хорошим. - person Halo; 26.07.2010

Отправной точкой здесь является создание декартова соединения между вашими типами и вашим temptable (предположим, что структура ваших таблиц: type(id, type), valueTable(id, type_id, some_value))

Следующий запрос

SELECT t.type, SUM(vt.someValue)/COUNT (*) AS sum FROM type t, valueTable vt WHERE vt.type_id != t.id GROUP BY t.type

должен сделать трюк.

person Killerwhile    schedule 23.07.2010
comment
спасибо, хотя я вставляю в valueTable. В начале есть только соблазн - person Halo; 23.07.2010

Будет ли это делать то, что вам нужно?

(Возможно, с другим оператором CASE, чтобы избежать ошибок деления на ноль, если есть вероятность, что ни один из типов не может быть возвращен, я также явно не учитывал случай, когда type имеет значение NULL)

SELECT

SUM(CASE WHEN TYPE <> 'Type1' THEN someValue ELSE 0 END) / 
     SUM(CASE WHEN TYPE = 'Type1' THEN 1 ELSE 0 END) AS T1,

SUM(CASE WHEN TYPE <> 'Type2' THEN someValue ELSE 0 END) / 
     SUM(CASE WHEN TYPE = 'Type2' THEN 1 ELSE 0 END) AS T2,

SUM(CASE WHEN TYPE <> 'Type3' THEN someValue ELSE 0 END) / 
     SUM(CASE WHEN TYPE = 'Type3' THEN 1 ELSE 0 END) AS T3,

SUM(CASE WHEN TYPE <> 'Type4' THEN someValue ELSE 0 END) / 
     SUM(CASE WHEN TYPE = 'Type4' THEN 1 ELSE 0 END) AS T4
FROM TEMPTABLE
person Martin Smith    schedule 23.07.2010
comment
спасибо, это на самом деле неплохая идея, но вместо этого я вычел текущее значение из суммы и разделил ее на (COUNT -1) - person Halo; 26.07.2010

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

SELECT type, avg(col_01)
FROM myTable
GROUP BY type
person Jamie LaMorgese    schedule 23.07.2010

Должен работать и на Sybase:

SELECT
   SUM(some value) / SUM(CASE WHEN TYPE = 1 THEN 1 ELSE 0 END)
FROM TEMPTABLE
GROUP BY TYPE
person Florian Reischl    schedule 23.07.2010
comment
да, это правда, но запрос будет делать это для каждого типа. поэтому я не хочу использовать постоянное значение - person Halo; 23.07.2010