简体   繁体   中英

How to get the aggregate results for missing values as zero

My DDL is like

create table if not exists sample_t
(
  id              bigserial NOT NULL constraint sample_t_id primary key,
  test_value varchar(255),
  test    varchar(255) not null,
  count     bigint not null
);

Sample insert queries

INSERT INTO public.sample_t (id, test_value, test, count) VALUES (1, 'CC1', 'hi-1', 11);
INSERT INTO public.sample_t (id, test_value, test, count) VALUES (2, 'CC2', 'hi-1', 10);
INSERT INTO public.sample_t (id, test_value, test, count) VALUES (3, 'CC1', 'hi-2', 4);

My Query is

select test, sum(count) from sample_t where test_value= 'CC2'  group by test;

The o/p is

test | sum
hi-1 | 10

However, I want to list down missing 'test' column values as 0. So the expected o/p should look like:

test | sum
hi-1 | 10
hi-2 | 0

Instead, use conditional aggregation:

select test, sum(case when test_value = 'CC2' then count else 0 end)
from sample_t
group by test;

Alternatively, if you have a table of all test values:

select t.test, coalesce(sum(count), 0)
from test t left join
     sample_t s
     on s.test = t.test and s.test_value = 'CC2'
group by t.test;

The problem here is that your WHERE clause might completely filter off a test group, should none of its records have the matching test value. You may use a left join here to preserve every initial test value:

SELECT DISTINCT
    s1.test,
    COALESCE(s2.cnt, 0) AS cnt
FROM sample_t s1
LEFT JOIN
(
    SELECT test, COUNT(*) AS cnt
    FROM sample_t
    WHERE test_value = 'CC2'
    GROUP BY test
) s2
    ON s1.test = s2.test;

Or, you could use conditional aggregation:

SELECT
    test, COUNT(CASE WHEN test_value = 'CC2' THEN 1 END) cnt
FROM sample_t
GROUP BY test;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM