Reputation: 6342
I use PostgreSQL, and I'd love to trim the date if it's out of the range.
First thing I'd love to filter the records out of the range. It's not difficult with query below. (Filter from 2017/3/1 ~ 2017/3/31)
select * from subscriptions where current_period_start_at <= date '2017/03/01' AND current_period_end_at >= date '2017/03/31'
However I'd love to cut off the date if it's out of the range(2017-03-1 ~ 2017-03-31
).
current_period_start_at: 2017/02/25
=> 2017/03/01
current_period_end_at: 2017/04/02
=> 2017/03/31
Here is some example.
target 2016/08/05 ~ 2016/09/15
range① 2016/07/01 ~ 2016/08/31 => 2016/08/05 ~ 2016/08/31
range② 2016/08/10 ~ 2016/09/20 => 2016/08/10 ~ 2016/09/15
range③ 2016/09/15 ~ 2016/10/10 => x out of the scope
range④ 2016/08/01 ~ 2016/09/30 => 2016/08/05 ~ 2016/09/15
Upvotes: 3
Views: 69
Reputation:
You can use the least()
function to get the lower of the values:
select greatest(current_period_start_at, date '2016-08-05') as range_start,
least(current_period_end_at, date '2016-09-15') as range_end
from subscriptions
where (current_period_start_at,current_period_end_at)
overlaps (date '2016-08-05', date '2016-09-15');
If you don't want to repeat the date value, you can use a common table expression:
with range (r_start, r_end) as (
values (date '2016-08-05', date '2016-09-15')
)
select greatest(current_period_start_at, r_start) as range_start,
least(current_period_end_at, r_end) as range_end
from subscriptions, range
where (current_period_start_at,current_period_end_at)
overlaps (r_start, r_end);
Upvotes: 4
Reputation: 5930
You should try daterange datatype.
SELECT daterange('2017-01-01'::date, '2017-03-01'::date) * daterange('2017-02-15'::date, '2017-05-01'::date);
returns
[2017-02-15,2017-03-01)
Upvotes: 3