I have an SQL query that is doing some calculations. Beyond simple formatting changes, I am wondering if it is possible to somehow utilise CTEs to make this query easier to read? I have found a few opportunities where using CTEs can make a big difference to query understandability, but doing it with this query eludes me.
Schema:
CREATE TABLE public.items (
id bigint NOT NULL,
uuid uuid NOT NULL,
);
CREATE TABLE public.download_counts (
item_id uuid NOT NULL,
date date NOT NULL,
download_count integer NOT NULL,
);
CREATE TABLE public.view_counts (
item_id uuid NOT NULL,
date date NOT NULL,
view_count integer NOT NULL,
);
Query:
select
i.uuid as item_id,
(
(
sum(dlw.download_count) * (
case
when sum(vlw.view_count) = 0 then sum(dlw.download_count)
else sum(vlw.view_count)
end
)
) - (
sum(dpw.download_count) * (
case
when sum(vpw.view_count) = 0 then sum(dpw.download_count)
else sum(vpw.view_count)
end
)
)
) * 100 / (
sum(dpw.download_count) * (
sum(dpw.download_count) * (
case
when sum(vpw.view_count) = 0 then sum(dpw.download_count)
else sum(vpw.view_count)
end
)
)
) as trending_score
from
items as i
left join download_counts as dlw
on dlw.item_id = i.uuid
and dlw.date between (now()::date - interval '1 week') and (now()::date - interval '1 day')
left join download_counts as dpw
on dpw.item_id = i.uuid
and dpw.date between (now()::date - interval '2 week') and (now()::date - interval '8 days')
left join view_counts as vlw
on vlw.item_id = i.uuid
and vlw.date between (now()::date - interval '1 week') and (now()::date - interval '1 day')
left join view_counts as vpw
on vpw.item_id = i.uuid
and vpw.date between (now()::date - interval '2 week') and (now()::date - interval '8 days')
where dlw.item_id is not null or dpw.item_id is not null or vlw.item_id is not null or vpw.item_id is not null
group by i.uuid;
Can I use CTEs or some other refactoring technique to make this query easier to understand? Thanks!