Fill in missing rows when aggregating over multiple fields in Postgres

后端 未结 2 1391
温柔的废话
温柔的废话 2021-01-18 08:35

I am aggregating sales for a set of products per day using Postgres and need to know not just when sales do happen, but also when they do not for further processing.

2条回答
  •  再見小時候
    2021-01-18 09:23

    You could use:

    WITH cte AS (
       SELECT date, s.product
       FROM  ... -- some way to generate date series
       CROSS JOIN (SELECT DISTINCT product FROM sales_data) s
    )
    SELECT 
        c.date,
        c.product,
        COUNT(sd.sale_id) AS sales
    FROM cte c
    LEFT JOIN sales_data sd
      ON c.date = sd.date AND c.product= sd.product
    GROUP BY c.date, c.product
    ORDER BY c.date, c.product;
    

    First create Cartesian product of dates and products, then LEFT JOIN to actual data and do calculations.


    Oracle has great feature for this scenarios called Partitioned Outer Joins:

    SELECT times.time_id, product, quantity 
    FROM inventory  PARTITION BY  (product) 
    RIGHT OUTER JOIN times ON (times.time_id = inventory.time_id) 
    WHERE times.time_id BETWEEN TO_DATE('01/04/01', 'DD/MM/YY') 
          AND TO_DATE('06/04/01', 'DD/MM/YY') 
    ORDER BY  2,1; 
    

提交回复
热议问题