SUM() по условию

CREATE TABLE sample (
  id int,
  num int,
  cond BOOLEAN
);

INSERT INTO sample (id, num, cond) VALUES
(1, 100, true),
(1, 20, true),
(1, 50, false),
(1, 75, false),
(2, 20, false),
(2, 80, true),
(2, 50, false),
(1, 10, true);

Выводим сумму num для каждого id

SELECT id, SUM(num) FROM sample GROUP BY id;
 id | sum 
----+-----
  2 | 150
  1 | 255

Здесь тоже самое, но с условием, что cond = true

SELECT id, SUM(num) AS sum_with_true_cond FROM sample WHERE cond = true GROUP BY id;
 id | sum_with_true_cond 
----+--------------------
  2 |                 80
  1 |                130

Здесь cond = false

SELECT id, SUM(num) AS sum_with_false_cond FROM sample WHERE cond = false GROUP BY id;  
 id | sum_with_false_cond 
----+---------------------
  2 |                  70
  1 |                 125

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

 id | sum_with_true_cond | sum_with_false_cond 
----+--------------------+---------------------
  2 |                 80 |                  70
  1 |                130 |                 125

Опции просмотра комментариев

Выберите предпочитаемый вами способ показа комментариев и нажмите "Сохранить настройки" для активации изменений.

А сделать два отдельных

А сделать два отдельных запроса, а потом либо JOIN либо UNION пробовали?

SELECT id, SUM(num) AS

SELECT id, SUM(num) AS sum_with_true_cond FROM sample AS t1 WHERE cond = true GROUP BY id
UNION ( SELECT id, SUM(num) AS sum_with_false_cond FROM sample AS t2 WHERE cond = false GROUP BY id );
 id | sum_with_true_cond 
----+--------------------
  1 |                125
  1 |                130
  2 |                 70
  2 |                 80

Это не совсем то что нужно

SELECT t.id, MAX(t1.sum) AS sum_with_true_cond, MAX(t2.sum) AS sum_with_false_cond FROM sample AS t
LEFT JOIN (SELECT id, SUM(num) FROM sample WHERE cond = true GROUP BY id) AS t1 USING(id)
LEFT JOIN (SELECT id, SUM(num) FROM sample WHERE cond = false GROUP BY id) AS t2 USING(id)
GROUP BY t.id;

Здесь я использую t для избежания ситуации, когда окажутся записи с cond = true, а с cond = false - нет, или наоборот.
Может можно упростить ?

Здесь вряд ли, потому что вы

Здесь вряд ли, потому что вы хотите дважды обсчитать одну таблицу по разным условиям. Так что по факту у вас получается две разные таблицы, которые имеют одну общую колонку id, по которой и можно выполнить JOIN. Я бы написал что-то типа:

SELECT t1.id, t1.s, t2.s FROM
(SELECT id, SUM(num) AS s
FROM sample WHERE cond = true GROUP BY id) AS t1,
(SELECT id, SUM(num) AS s
FROM sample WHERE cond = false GROUP BY id) AS t2
WHERE t1.id=t1.id;
<code>
 
Сорри, СУБД не под рукой, проверить на корректность не могу

я не тормоз... SELECT

я не тормоз...

SELECT id,
SUM( case when cond then 0 else num end ) AS sum_with_true_cond,
SUM( case when cond then num else 0 end ) AS sum_with_false_cond
FROM sample GROUP BY id;

Опции просмотра комментариев

Выберите предпочитаемый вами способ показа комментариев и нажмите "Сохранить настройки" для активации изменений.

Back to top

(С) Виктор Вислобоков, 2008-2023