-1

So i have a table of Subscription Cancellations that has the following schema: USER_ID, CANCEL_TYPE, OCCURRED_AT.

CANCEL_TYPE can take a range of values: "Cancelled Free Trial", "Cancelled Paying", "Set Cancellation".

I want to group by OCCURRED_AT and CANCEL_TYPE to get a COUNT(USER_ID) for each cancel_type on each day - basically giving the total number of occurrences of each type of cancellation on each day.

Here's my statement at the moment:

select
    extract(date from occurred_at) as date, cancel_type, COUNT(customer_id) as total
from TABLE
group by date, cancel_type
order by date, cancel_type

Problem is, some days nobody cancels a subscription or not all cancel_types occur. How can I edit this statement to return all cancel_types for all dates with 0 or NULL values if they don't occur?

Asher Canessa
  • 63
  • 1
  • 1
  • 4

2 Answers2

1

You can have 2 CTE on top for cancel types and Dates. And then cross join Dates to Cancel types and left join this to your table. You can change order by and group by as you require

WITH Dates AS (
    SELECT DISTINCT DATE_TRUNC('DAY', occurred_at) AS date
    FROM TABLE),
 
CancelTypes AS (
    SELECT DISTINCT cancel_type
    FROM TABLE)

SELECT
    d.date,
    ct.cancel_type,
    COALESCE(COUNT(t.customer_id), 0) AS total
FROM
    Dates d
CROSS JOIN
    CancelTypes ct
LEFT JOIN
    TABLE t
    ON d.date = DATE_TRUNC('DAY', t.occurred_at)
    AND ct.cancel_type = t.cancel_type
GROUP BY
    d.date, ct.cancel_type
ORDER BY
    d.date, ct.cancel_type;

0

You need to change your approach. For the sequence of (interested) dates then for the set of cancel types ask the data source for counts.

You can take an idea to get the sequence of dates here.

For the cancel type use IN:

CANCEL_TYPE IN ('Cancelled Free Trial', 'Cancelled Paying', 'Set Cancellation')
rotabor
  • 561
  • 2
  • 10