Postgresql Select from date range between array of dates
·
Answer a question
If this query returns the dates that exists in the range requested.
select created_at from user where created_at between '2015-01-06 00:00:00.000000' and '2015-03-06 00:00:00.000000'
Is there a way to obtain such result but with multiple dates contained with an array of dates.
Just for an example of what im trying to say. i have this array of date, always there's gonna be a first and last date.
Array['2015-01-06 00:00:00.000000','2015-02-10 15:17:18.895000' <- First range
'2017-10-05 14:41:04.191000','2017-10-11 14:49:36.454000' <- Second range
so is there a way to put a script that goes something like this?
select created_at from win_users
where (created_at between [First Date] and [Second Date])
or (created_at between [Third Date] and [Fourth Date])
but without using a loop to concat the where statement?
Answers
An array of dates is very uncomfortable in this case. Use arrays of daterange and the containtment operator <@, e.g.:
with my_table(id, created_at) as (
values
(1, '2015-01-10'::timestamp),
(2, '2016-05-10'),
(3, '2017-10-10')
)
select *
from my_table
where created_at::date <@ any(array[
daterange('2015-01-06','2015-02-10'),
daterange('2017-10-05','2017-10-11')])
id | created_at
----+---------------------
1 | 2015-01-10 00:00:00
3 | 2017-10-10 00:00:00
(2 rows)
If you absolutely want to use an array of dates (honestly I do not think so), use this function to convert it to daterange array:
create or replace function date_pairs_to_ranges(date[])
returns daterange[] language sql as $$
select array_agg(daterange(d1, d2))
from unnest($1) with ordinality as u1(d1, o1)
join unnest($1) with ordinality as u2(d2, o2)
on o1/ 2* 2 < o1 and o2 = o1+ 1
$$;
with my_table(id, created_at) as (
values
(1, '2015-01-10'::timestamp),
(2, '2016-05-10'),
(3, '2017-10-10')
)
select *
from my_table
where created_at::date <@ any(
date_pairs_to_ranges(array[
'2015-01-06','2015-02-10',
'2017-10-05','2017-10-11']::date[]))
更多推荐
所有评论(0)