Postgresql Select 来自日期数组之间的日期范围
Postgresql Select from date range between array of dates
如果此查询 returns 存在于请求范围内的日期。
select created_at from user where created_at between '2015-01-06 00:00:00.000000' and '2015-03-06 00:00:00.000000'
有没有办法获得这样的结果,但日期数组中包含多个日期。
只是为了举例说明我想说的话。我有这个日期数组,总是会有第一个和最后一个日期。
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
那么有没有办法放置这样的脚本?
select created_at from win_users
where (created_at between [First Date] and [Second Date])
or (created_at between [Third Date] and [Fourth Date])
但没有使用循环来连接 where 语句?
如果您的范围数组始终采用您发布的格式(即 4 个项目,前两个元素是第一个范围,后两个元素是第二个范围),那么您可以编写这样的查询:
WITH ranges AS (
SELECT '{2015-01-06 00:00:00.000000,2015-02-10 15:17:18.895000,2017-10-05 14:41:04.191000,2017-10-11 14:49:36.454000}'::date[] dates
)
SELECT win_users.created_at FROM win_users, ranges
WHERE (win_users.created_at > ranges.dates[1] AND win_users.created_at < ranges.dates[2]) OR (win_users.created_at > ranges.dates[3] AND win_users.created_at < ranges.dates[4]);
在这种情况下,一组日期非常不舒服。使用 daterange
and the containtment operator <@
的数组,例如:
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)
如果您绝对想使用日期数组(老实说我不这么认为),请使用此函数将其转换为日期范围数组:
create or replace function date_pairs_to_ranges(date[])
returns daterange[] language sql as $$
select array_agg(daterange(d1, d2))
from unnest() with ordinality as u1(d1, o1)
join unnest() 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[]))
如果此查询 returns 存在于请求范围内的日期。
select created_at from user where created_at between '2015-01-06 00:00:00.000000' and '2015-03-06 00:00:00.000000'
有没有办法获得这样的结果,但日期数组中包含多个日期。
只是为了举例说明我想说的话。我有这个日期数组,总是会有第一个和最后一个日期。
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
那么有没有办法放置这样的脚本?
select created_at from win_users
where (created_at between [First Date] and [Second Date])
or (created_at between [Third Date] and [Fourth Date])
但没有使用循环来连接 where 语句?
如果您的范围数组始终采用您发布的格式(即 4 个项目,前两个元素是第一个范围,后两个元素是第二个范围),那么您可以编写这样的查询:
WITH ranges AS (
SELECT '{2015-01-06 00:00:00.000000,2015-02-10 15:17:18.895000,2017-10-05 14:41:04.191000,2017-10-11 14:49:36.454000}'::date[] dates
)
SELECT win_users.created_at FROM win_users, ranges
WHERE (win_users.created_at > ranges.dates[1] AND win_users.created_at < ranges.dates[2]) OR (win_users.created_at > ranges.dates[3] AND win_users.created_at < ranges.dates[4]);
在这种情况下,一组日期非常不舒服。使用 daterange
and the containtment operator <@
的数组,例如:
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)
如果您绝对想使用日期数组(老实说我不这么认为),请使用此函数将其转换为日期范围数组:
create or replace function date_pairs_to_ranges(date[])
returns daterange[] language sql as $$
select array_agg(daterange(d1, d2))
from unnest() with ordinality as u1(d1, o1)
join unnest() 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[]))