2015-08-21 3 views
0

У меня есть следующая таблица (назовем его просто table):Как вычислить количество условием

id  name   value  group_id 
PK varchar(32) integer  integer 

Теперь мне нужно написать запрос, который возвращает меня SUM(value), сгруппированные по group_id и COUNT(name) где name like '%me%' (Мне не нужно просто вычислять граф, сгруппированный по group_id, мне нужно вычислить, что счетчик удовлетворяет условию).

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

ответ

3

С 9.4 вы можете использовать фильтрованную агрегат:

select group_id, 
     sum(value) 
     count(name) filter (where name like '%me%') 
from the_table 
group by group_id; 

Для более ранних версий, вам необходимо использовать саз:

select group_id, 
     sum(value) 
     count(case when name like '%me%' then 1 end) 
from the_table 
group by group_id; 

Это работает, потому что агрегаты будут игнорировать нулевые значения и case заявление вернет NULL, если имя не соответствует

+0

Прохладный, спасибо, но что, если я в 9.2? Должен ли я писать пользовательские аггрегаты? –

+1

@ St.Antario: см. Мое редактирование (или обновление до текущей версии;)) –

+0

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

2

Следует отметить, что случай может быть заменен литьем логического значения в целом, которое короче (LIKE можно заменить ~~, но это как короче и менее читаемый).

SELECT group_id 
     ,Sum(value) AS sum_value 
     ,Sum((name LIKE '%me%')::int) AS count_value 
FROM  table 
GROUP BY group_id; 
Смежные вопросы