My question is similar to https://stackoverflow.com/a/41267928/2585154 , but in my case I need to divide/split date range by multiple date ranges, not only one.
In my case is also guaranteed that "date ranges to split by" will not overlap with each other.
Example 1:
Date range to split: 2021年01月01日 2021年12月31日
Date ranges to split by (1):
- 2021年03月01日 2021年06月02日
I want to get following output:
- 2021年01月01日 2021年02月28日
- 2021年06月03日 2021年12月31日
Example 2:
Date range to split: 2021年01月01日 2021年12月31日
Date ranges to split by (2):
- 2021年03月01日 2021年06月02日
- 2021年07月01日 2021年12月30日
I want to get following output:
- 2021年01月01日 2021年02月28日
- 2021年06月03日 2021年06月30日
- 2021年12月31日 2021年12月31日
-
1Please consider following these suggestions.mustaccio– mustaccio2021年11月28日 20:04:23 +00:00Commented Nov 28, 2021 at 20:04
-
Combine date range to split and date ranges to strip out marking the dates with flag IN/OUT (for date range which you need to split the start is marked as IN, for date ranges for to strip the starts are OUT). Then simply process this dates list and select subranges between IN and adjacent OUT.Akina– Akina2021年11月28日 20:09:28 +00:00Commented Nov 28, 2021 at 20:09
1 Answer 1
The new multirange data types in Postgres 14 are exactly what you need.
Multirange operators allow to split a date range.
The release notes for Postgres 14:
Add support for multirange data types (Paul Jungwirth, Alexander Korotkov)
These are like range data types, but they allow the specification of multiple, ordered, non-overlapping ranges. An associated multirange type is automatically created for every range type.
Example 1:
test=> SELECT datemultirange '{[2021年01月01日,2022年01月01日)}'
test-> - datemultirange '{[2021年03月01日,2021年06月02日]}' AS result;
result
---------------------------------------------------
{[2021年01月01日,2021年03月01日),[2021年06月03日,2022年01月01日)}
(1 row)
Example 2:
test=> SELECT datemultirange '{[2021年01月01日,2021年12月31日]}'
test-> - datemultirange '{[2021年03月01日,2021年06月02日], [2021年07月01日,2021年12月30日]}' AS result;
result
---------------------------------------------------------------------------
{[2021年01月01日,2021年03月01日),[2021年06月03日,2021年07月01日),[2021年12月31日,2022年01月01日)}
(1 row)
db<>fiddle here
I'm using multirange literals (constants) in my example.
The manual on how to construct multiranges.
Note that [2021年01月01日,2022年01月01日)
and [2021年01月01日,2021年12月31日]
are two equivalent syntax variants for the same the date ranges. The first variant is the canonical form. The manual:
The built-in range types
int4range
,int8range
, anddaterange
all use a canonical form that includes the lower bound and excludes the upper bound; that is,[)
. User-defined range types can use other conventions, however.
-
Thanks a lot! That is exactly what I need :)Dmitry K.– Dmitry K.2021年11月28日 22:34:33 +00:00Commented Nov 28, 2021 at 22:34
Explore related questions
See similar questions with these tags.