1

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日
asked Nov 28, 2021 at 19:57
2
  • 1
    Please consider following these suggestions. Commented 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. Commented Nov 28, 2021 at 20:09

1 Answer 1

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, and daterange 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.

answered Nov 28, 2021 at 22:24
1
  • Thanks a lot! That is exactly what I need :) Commented Nov 28, 2021 at 22:34

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.