Как применить случай, когда оператор после группы по предложению

ВВОД:

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

    date   | is_shipped | is_realised | mrp  
----------+------------+-------------+------
 12022015 |          1 |           1 | 1000
 12022015 |          0 |           1 | 2000
 12022015 |          1 |           0 | 3000
 13022015 |          1 |           1 | 1500
 13022015 |          0 |           1 | 2500
 13022015 |          1 |           0 | 3500

ПОСТАНОВКА ПРОБЛЕМЫ:

Я хочу сгруппировать строки по дате, чтобы получить общий MRP, а также MRP, соответствующий is_shipped = 1 и is_realised = 1. Например, общий MRP на 12022015 равен 1000 + 2000 + 3000 = 6000. Общий MRP, соответствующий is_shipped = 1 на 12022015, равен 1000 + 3000 = 4000. Общий MRP, соответствующий is_realised = 1 на 12022015, равен 1000 + 2000 = 3000.

ОЖИДАЕМЫЙ РЕЗУЛЬТАТ

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

    date   | shipped_mrp | realised_mrp | mrp  
----------+-------------+--------------+------
 12022015 |        4000 |         3000 | 6000
 13022015 |        5000 |         4000 | 7500

ПОПЫТКА РЕШЕНИЯ:

Я попробовал следующий запрос, который не работает:

select sum(mrp),
CASE WHEN is_realised = 1
THEN 
    SUM(mrp)
ELSE
    0
END AS realised_mrp,
CASE WHEN is_shipped = 1
THEN 
    SUM(mrp)
ELSE
    0
END AS shipped_mrp
from rev
group by date;

ОШИБКА:

Я получаю следующую ошибку:

столбец "rev.is_realised" должен присутствовать в предложении GROUP BY или использоваться в агрегатной функции. СТРОКА 2: СЛУЧАЙ, КОГДА is_realized = 1.


person nish    schedule 10.08.2015    source источник


Ответы (2)


Переместите оператор case внутрь функции sum:

select 
  date, 
  sum(CASE WHEN is_shipped = 1 THEN mrp ELSE 0 END) AS shipped_mrp,
  sum(CASE WHEN is_realised = 1 THEN mrp ELSE 0 END) AS realised_mrp,
  sum(mrp) AS mrp
from rev
group by date;

Пример скрипта SQL

person jpw    schedule 10.08.2015
comment
Потрясающий. Работает отлично. Спасибо! - person nish; 10.08.2015

При использовании PG9.4+ используйте гораздо более эффективное предложение FILTER:

SELECT "date",
       sum(mrp) FILTER (WHERE is_shipped = 1) AS shipped_mrp,
       sum(mrp) FILTER (WHERE is_realised = 1) AS realised_mrp,
       sum(mrp) AS mrp
FROM rev
GrOUP BY 1;
person Patrick    schedule 10.08.2015