Возможно я не прав, возможно я в вел почтенную публику в заблуждение.
Смысл всей этой затеи в том, что есть организации у каждой их них есть некторое количество итемов пребывающих в неких состояниях, соответственно хотелось-бы получить одним запросом количество итемов в тех или иных состояниях для всех организаций.
Как таковой total не интересет так как он легко получается из суммы всех статусов организации.
Как мне показалось запрос приведенный в начале ветки, самый простой, который решает задачу "в лоб",
Возможно так будет оптимальнее:
SELECT
org_id,
SUM(count) AS total,
SUM(CASE WHEN status = 0 THEN count ELSE 0 END) AS status0,
SUM(CASE WHEN status = 1 THEN count ELSE 0 END) AS status1,
SUM(CASE WHEN status = 2 THEN count ELSE 0 END) AS status2,
SUM(CASE WHEN status = 3 THEN count ELSE 0 END) AS status3
FROM (
SELECT org_id, status, count(*) as count
FROM org_item
GROUP BY org_id, status
) AS status
GROUP BY org_id
Но все равно план выполнения:
HashAggregate (cost=30023.09..30025.09 rows=200 width=18) (actual time=278.918..279.648 rows=1862 loops=1)
-> HashAggregate (cost=29775.10..29830.21 rows=5511 width=10) (actual time=273.322..274.256 rows=2687 loops=1)
-> Seq Scan on org_item (cost=0.00..27670.77 rows=280577 width=10) (actual time=0.057..118.753 rows=281149 loops=1)
Total runtime: 280.044 ms
Да, индекс покрывающий org_id + status имеется:
CREATE INDEX org_item_idx_org_status ON org_item USING btree (org_id, status);