#sql #postgresql
#sql #postgresql
Вопрос:
таблица 1
person | zipcode | timestamp | event | device
--------------------------------------------------|--------|------
amar | 11111 | 2016-09-28 20:05:03.001 | email | phone
akbar | 11111 | 2016-09-28 20:05:03.001 | email | phone
antony | 11111 | 2016-09-28 20:07:03.001 | chat | pc
amar | 11111 | 2016-09-28 20:08:03.001 | email | phone
amar | 11111 | 2016-09-28 20:08:03.001 | chat | phone
amar | 22222 | 2016-09-28 20:09:03.001 | email | phone
akbar | 22222 | 2016-09-28 20:10:03.001 | email | phone
antony | 22222 | 2016-09-28 20:10:03.001 | chat | phone
amar | 11111 | 2016-09-28 21:05:03.001 | email | phone
akbar | 11111 | 2016-09-28 21:05:03.001 | email | phone
antony | 11111 | 2016-09-28 21:07:03.001 | chat | phone
желаемый результат
person | total_events | email_events
---------------------------------------
amar | 5 | 4
akbar | 3 | 3
antony | 3 | 0
Подумываю использовать group by
для этого, как показано ниже — как получить количество событий, где event = 'email'
здесь — есть ли способ сделать это без использования подвыборки?
select
person
, count (*) as total_events
from table1
group by person
Комментарии:
1.
... count(*) filter (where event = 'email') as email_events
Ответ №1:
Добавьте условие в CASE
инструкцию и оберните его в COUNT
aggregate
Попробуйте это
select
person
, count (*) as total_events
, Count(case when event = 'email' then 1 end) as email_events
from table1
group by person
Комментарии:
1. Кстати, немного проще:
..., count(nullif(event = 'email', false)) ...
Ответ №2:
Используйте group by
вместе с case
:
select person,
count(*) as total_events,
sum(case when event = 'email' then 1 else 0 end) as email_events
from table1
group by person;
В Postgres вы можете сократить это до:
select person,
count(*) as total_events,
sum( (event = 'email')::int ) as email_events
from table1
group by person;