0

Hi have a table like this : invoice_type have only three value "direct","promotion" or "giftcode"

enter image description here

i want to result like this:

enter image description here

my code is:

SELECT table1.user_id, count_direct,count_promotion,count_giftcode,direct_plan, promotion_plan, giftcode_plan
    from (SELECT invoices_map.user_id,
            sum(CASE WHEN invoice_type='direct' THEN 1 ELSE 0  END) as count_direct,
            sum(CASE WHEN invoice_type='promotion' THEN 1 ELSE 0  END) as count_promotion,
            sum(CASE WHEN invoice_type='giftcode' THEN 1 ELSE 0  END) as count_giftcode,
            FROM payment.invoices_map
            group by user_id) as table1
    left join (Select user_id,array_agg(distinct plan_type) as direct_plan
                from payment.invoices_map
                where plan_type= 'direct' 
                group by user_id) as direct_plan_tb on table1.user_id = direct_plan_tb.user_id
    left join (Select user_id,array_agg(distinct plan_type) as 
                from payment.invoices_map
                where plan_type= 'promotion' 
                group by user_id) as promotion_plan_tb on table1.user_id = promotion_plan_tb.user_id
    left join (Select user_id,array_agg(distinct plan_type) as 
                from payment.invoices_map
                where plan_type= 'giftcode' 
                group by user_id) as giftcode_plan_tb on table1.user_id = giftcode_plan_tb.user_id

It shows correct answer but I want to optimize my code

thoai nguyen
  • 35
  • 1
  • 8
  • this may help you. https://stackoverflow.com/questions/20618323/create-a-pivot-table-with-postgresql – zealous May 14 '20 at 05:58
  • 1
    Does this answer your question? [Create a pivot table with PostgreSQL](https://stackoverflow.com/questions/20618323/create-a-pivot-table-with-postgresql) – zealous May 14 '20 at 05:58

1 Answers1

0

You can simplify this to a single statement using conditional aggregation.

However, this part of your derived tables:

array_agg(distinct plan_type) as direct_plan
...
where plan_type= 'direct' 

seems wrong because the aggregated column and the filter column are identical. I assume you actually meant to aggregate the plan_type column and filter on the invoice_type column (at least after looking at the screen shots).

So the simplified statement would look like this:

SELECT im.user_id,
       array_agg(distinct im.plan_type) filter (where im.invoice_type = 'direct') as direct_plan,
       array_agg(distinct im.plan_type) filter (where im.invoice_type = 'promotion') as promotion_plan,
       array_agg(distinct im.plan_type) filter (where im.invoice_type = 'giftcode') as giftcode_plan,
       count(*) filter (where invoice_type = 'direct') as count_direct,
       count(*) filter (where invoice_type = 'promotion') as count_promotion,
       count(*) filter (where invoice_type = 'giftcode') as count_giftcode,
FROM payment.invoices_map im
group by user_id