I have a product table that has this structure:
id product_id phase_type phase_start phase_end
1 1 Obsolete 2025-01-01 null
2 1 GA 2022-01-01 null
I want to check if a product is between dates, but in this case phase_end
is null, so I want to get the phase_start
of Obsolete
and use it as if it is the phase end of GA
to check whether this product is within a time interval of 6 months before the phase_end:
select
id,
product_id,
phase_type,
phase_start,
phase_end,
(
case
when phase_type = 'GA'
and phase_end is null
and current_date between (phase_start_of_obsolete - interval '6 month')::date and phase_start_of_obsolete then true
else false
end
) as current_phase
from table_product
Above the value phase_start_of_obsolete
is pseudo-code and indicates i would like to have the phase start date of the same product when that phase is Obsolete. I tried some self joins of the table with itself , but i believe a self join inside a CASE expression might be a very expensive/slow query to make. Is there a better approach to this problem ?
My desired result would look like:
id product_id phase_type phase_start phase_end current_phase
1 1 Obsolete 2025-01-01 null false
2 1 GA 2022-01-01 null true
2
Answers
One way to do it is a self-join using an
EXISTS
clause:phase_end
is currentlyFALSE
for both rows, because it is still 2023.The following query returns the requested result without
CASE
statements or self-joins:An alternative form using
BETWEEN
instead of a multirange is:Instead of checking against a 6 month range, it might be sufficient to simply determine that the current date is later than 6 months prior to the beginning of the "Obsolete" phase.
A
CASE
expression isn’t needed because the logical value can be directly evaluated. In general, whenever a logical value is required, avoid usingCASE
and explicitly setting the value: it is unnecessarily verbose and creates additional opportunities to introduce code defects.