如何在不使用FULL OUTER JOIN的情况下有条件地分组到列中

时间:2018-01-23 06:50:45

标签: postgresql

我想转

TABLEA:
id      type               amount
A       'Customer'          100
A       'Parter'            10
A       'Customer'          200
A       'Parter'            20
B       'Parter'            555

我可以硬编码类型,不需要动态,这些类型是枚举

RESULT:
id      customer_array  customer_sum   partner_array  partner_sum 
A       [100, 200]      300            [10, 20]       30           
B       []              0              [555]          555             

现在    我正在使用两个聚合函数

   WITH customer AS (
      SELECT
        table_A,
        json_agg(row_to_json(amount)) AS customer_array,
        sum(amount)                   AS customer_sum
      FROM table_A WHERE type='Customer' 
      GROUP BY id
   ), partner AS (
      SELECT
        table_A,
        json_agg(row_to_json(amount)) AS partner_array,
        sum(amount)                   AS partner_sum
      FROM table_A WHERE type='Partner' 
      GROUP BY id
   ) SELECT 
       id,
       COALESCE(customer_array, '[]')    AS customer_array,
       COALESCE(customer_sum, 0)         AS customer_sum,
       COALESCE(partner_array, '[]')     AS partner_array,
       COALESCE(partner_sum, 0)          AS partner_sum
   FROM customer FULL OUTER JOIN partner USING (id)

我想知道是否有办法在不查询两次的情况下实现我想要的目标?

2 个答案:

答案 0 :(得分:3)

据我所知,这是一个简单的条件聚合:

select id, 
       array_agg(amount) filter (where type = 'Customer') as customer_array,
       sum(amount) filter (where type = 'Customer') as customer_sum,
       array_agg(amount) filter (where type = 'Partner') as partner_array,
       sum(amount) filter (where type = 'Partner') as partner_sum
from table_a
group by id;

如果您想要一个空数组而不是NULL值,请将聚合函数包装到coalesce()

select id, 
       coalesce((array_agg(amount) filter (where type = 'Customer')),'{}') as customer_array,
       coalesce((sum(amount) filter (where type = 'Customer')),0) as customer_sum,
       coalesce((array_agg(amount) filter (where type = 'Partner')),'{}') as partner_array,
       coalesce((sum(amount) filter (where type = 'Partner')),0) as partner_sum
from table_a
group by id;

答案 1 :(得分:0)

您可以尝试使用case语句。 https://www.postgresql.org/docs/8.2/static/functions-conditional.html

我没有postgres服务器来试试这个。但整体语法应如下所示。

    SELECT
        table_A,
        case 
            when Type='Customer' 
         then json_agg(row_to_json(amount)) 
         else [] 
         end AS customer_array,
        case 
            when Type='Customer' 
             sum(amount)  
             else 0 
        end
        AS customer_sum,

        case 
            when Type='Partner' 
         then json_agg(row_to_json(amount)) 
         else [] 
         end AS partner_array
        case 
            when Type='Partner' 
             sum(amount)  
             else 0 
        end
         From table_A
    GROUP BY id