I love to use CTEs to create nice and clear queries. However, I'm pretty sure the query I created is really inefficient.
Is there a better way to do this and keep things clear ?
with first_date as (
-- selecting just 1 date
-- namely: 1 full year ago
select (extract(year from current_date - interval '1 year')||'-01-01' )::date as date
)
, last_date as (
select date from star.dim_date where current_cal_day='Current'
)
, total_active_customers_ps_day as(
select
dd.date
, dd.is_first_day_in_month
, dd.is_last_day_in_month
, count(dc.id) as total_customers
from first_date, last_date,
star.dim_date dd
-- join with dim_client, using first_subscription_start_date & last_subscription_end_date
-- to get the ids of just the active clients
join star.dim_client dc on dd.date
between dc.first_subscription_start_date and coalesce(dc.last_subscription_end_date::date, '3000-01-01')
and dc.created <= dd.date
and dc.first_subscription_start_date >= dc.created::date
where
dd.date >= first_date.date
and dd.date <= last_date.date
group by
dd.date
, dd.is_first_day_in_month
, dd.is_last_day_in_month
)
select * from total_active_customers_ps_day ;
I think I'm causing some cartesian joins, since this query is far more efficient
with total_active_customers_ps_day as(
select
dd.date
, dd.is_first_day_in_month
, dd.is_last_day_in_month
, count(dc.id) as total_customers
from
star.dim_date dd
-- join with dim_client, using first_subscription_start_date & last_subscription_end_date
-- to get the ids of just the active clients
join star.dim_client dc on dd.date
between dc.first_subscription_start_date and coalesce(dc.last_subscription_end_date::date, '3000-01-01')
and dc.created <= dd.date
and dc.first_subscription_start_date >= dc.created::date
where
dd.date >= (extract(year from current_date - interval '1 year')||'-01-01' )::date
and dd.date <= (select date from star.dim_date where current_cal_day='Current')
group by
dd.date
, dd.is_first_day_in_month
, dd.is_last_day_in_month
)
select * from total_active_customers_ps_day ;
What's the better way to do this?