Skip to content
Advertisement

Group by combination count in postgresql

I have a database table as like table_name (participant_member) :

enter image description here

dataset and output formate link

I need combination based group by unique count for example if a member already stay in purpose p1 then it will not count inside p1,p2 combinaton if the member_id contain the purpose p1 and p2 then it will count inside p1,p2 enter image description here I have tryied using this query

This output generate based on the test input dataset.

I have tried a sql query but it does not give me the appropriate output as i like . its doesnt give me the unique one

with tmain as (select member_id, purpose, group_id, pg.name
from participant_group_member pgm
join participant_group pg on pg.id = pgm.group_id
join participant_group_type pgt on pg.participant_group_type_id = pgt.id
join program_pivoted pp on pp.program_id = pgt.component_id
where   purpose not like '%Test_জানিনা%'  and purpose not like '%Test_Apu_SAPLING%' and purpose not like '%Test Purpose -p1%'

),
cte as (SELECT string_agg( distinct tmain.purpose, ',' ORDER BY tmain.purpose) as pc,
count(*)                                              as cnt
from tmain
group by tmain.purpose
)
select pc       as purpose_combination,
sum(cnt) as member_count

from cte
group by pc

Note: I am using postgres database

Advertisement

Answer

I think the problem was with cte you should group by member to get the purpose combination of every member then count the member of every combination:

WITH tmain AS (
 SELECT 
   member_id,
   purpose,
   group_id,
   pg.name
FROM 
   participant_group_member pgm
       JOIN participant_group pg ON pg.id = pgm.group_id
       JOIN participant_group_type pgt ON pg.participant_group_type_id = pgt.id
       JOIN program_pivoted pp ON pp.program_id = pgt.component_id
WHERE   
     purpose not like '%Test_জানিনা%'  
     AND purpose not like '%Test_Apu_SAPLING%' 
     AND purpose not like '%Test Purpose -p1%'
),
-- HERE group by member to extract every purpose combination of a member
-- mem1  p1,p2
-- mem2  p1
-- mem3  p1,p2
-- when you group by purpose combination you get members by count them
--  p1,p2  : 2 members
--  p1      : 1 members 
cte as (
SELECT 
     tmain.member_id,
     string_agg( distinct tmain.purpose, ',' ORDER BY tmain.purpose) as pc
FROM tmain
group by 
  tmain.member_id
)
SELECT 
   cte.pc  as purpose_combination,
   count(*) as member_count
FROM cte
GROUP BY pc
User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement