Postgresql Несколько счетчиков для одной таблицы

Из двух столбцов в моей таблице я хочу получить единый счетчик для значений в этих столбцах. Например, два столбца:

Таблица: отчеты

|   type        |   place   |  
 ----------------------------------------- 
|   one         |   home    |  
|   two         |   school  |  
|   three       |   work    |  
|   four        |   cafe    |  
|   five        |   friends |  
|   six         |   mall    |  
|   one         |   work    |  
|   one         |   work    |  
|   three       |   work    |  
|   two         |   cafe    |  
|   five        |   cafe    |  
|   one         |   home    |  

Если я это сделаю: Тип SELECT, счетчик (*) из отчетов группа по типу

Я получаю:

|   type        |   count   |  
-----------------------------  
|   one         |   4       |  
|   two         |   2       |  
|   three       |   2       |  
|   four        |   1       |  
|   five        |   2       |  
|   six         |   1       | 

Im пытается получить что-то вроде этого: (один самый правый столбец с моими типами сгруппированы вместе и несколько столбцов со значениями count для каждого места) Я получаю:

|   type        |   home    |   school  |   work    |   cafe    |   friends |   mall    |  
-----------------------------------------------------------------------------------------  
|   one         |   2       |           |   2       |           |           |           |  
|   two         |           |   1       |           |   1       |           |           |  
|   three       |           |           |   2       |           |           |           |  
|   four        |           |           |           |   1       |           |           |  
|   five        |           |           |           |   1       |   1       |           |  
|   six         |           |           |           |           |           |   1       |  

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

SELECT type, count(*) from reports where place  = 'home'
group by type
SELECT type, count(*) from reports where place  = 'school'
group by type
SELECT type, count(*) from reports where place  = 'work'
group by type
SELECT type, count(*) from reports where place  = 'cafe'
group by type
SELECT type, count(*) from reports where place  = 'friends'
group by type
SELECT type, count(*) from reports where place  = 'mall'
group by type

Возможно ли это с помощью postgresql?

Спасибо заранее.

Ответ 1

вы можете использовать case в этом случае -

SELECT type, 
       sum(case when place  = 'home' then 1 else 0 end) as Home,
       sum(case when  place  = 'school' then 1 else 0 end) as school,
       sum(case when  place  = 'work' then 1 else 0 end) as work,
       sum(case when  place  = 'cafe' then 1 else 0 end) as cafe,
       sum(case when  place  = 'friends' then 1 else 0 end) as friends,
       sum(case when  place  = 'mall' then 1 else 0 end) as mall
  from reports
 group by type

Он должен решить вашу проблему

@S T Мохаммед, Чтобы получить такой тип, мы можем просто использовать using после group или where условие во внешнем запросе, как показано ниже -

select type, Home, school, work, cafe, friends, mall from (
SELECT type, 
       sum(case when place  = 'home' then 1 else 0 end) as Home,
       sum(case when  place  = 'school' then 1 else 0 end) as school,
       sum(case when  place  = 'work' then 1 else 0 end) as work,
       sum(case when  place  = 'cafe' then 1 else 0 end) as cafe,
       sum(case when  place  = 'friends' then 1 else 0 end) as friends,
       sum(case when  place  = 'mall' then 1 else 0 end) as mall
  from reports
 group by type
 )
 where home >0 and School >0 and Work >0 and cafe>0 and friends>0 and mall>0

Ответ 2

Ответ от Praktik Garg правильный, нет необходимости использовать else 0:

SELECT type, 
       sum(case when place  = 'home' then 1 end) as home,
       sum(case when  place  = 'school' then 1 end) as school,
       sum(case when  place  = 'work' then 1 end) as work,
       sum(case when  place  = 'cafe' then 1 end) as cafe,
       sum(case when  place  = 'friends' then 1 end) as friends,
       sum(case when  place  = 'mall' then 1 end) as mall
 from reports
 group by type

Вы также можете использовать следующий еще более короткий синтаксис:

SELECT type, 
       sum((place  = 'home')::int) as home,
       sum((place  = 'school')::int) as school,
       sum((place  = 'work' )::int) as work,
       sum((place  = 'cafe' )::int) as cafe,
       sum((place  = 'friends')::int) as friends,
       sum((place  = 'mall')::int) as mall
 from reports
 group by type

Это будет работать, потому что логическое значение true приводится к 1 при выполнении условия.

Ответ 3

Вы также можете использовать предложение фильтра:

SELECT
  type,
  sum(1) FILTER (WHERE place = 'home') AS home,
  sum(1) FILTER (WHERE place = 'school') AS school,
  sum(1) FILTER (WHERE place = 'work') AS work,
  sum(1) FILTER (WHERE place = 'cafe') AS cafe,
  sum(1) FILTER (WHERE place = 'friends') AS friends,
  sum(1) FILTER (WHERE place = 'mall') AS mall
FROM
  reports
GROUP BY 
  type