【问题标题】:Why does postgres' upper range function for a daterange return an exclusive bound?为什么 postgres 的日期范围上限函数返回独占边界?
【发布时间】:2016-06-21 20:15:07
【问题描述】:

我为这篇文章创建了一个 sql fiddle:http://sqlfiddle.com/#!15/7b5d7/1/0

问题 #1

为什么插入具有独占边界的daterange 的记录实际上存储了具有包含下限和独占上限的范围?为什么 pg 不将它们都存储为包含边界?

问题 #2

SELECT upper('[2016-06-19, 2016-06-21)'::daterange) 返回2016-06-21。请注意,[ 表示包含的下限,) 表示独占的上限。

不应该选择上限返回2016-06-20吗?日期没有离散间隔吗?

【问题讨论】:

  • 就是这样实现的。 From the manual: "内置范围类型 int4range、int8range 和 daterange 均使用包含下限但不包括上限的规范形式;即 [)" 和 @987654330 @ 与 [2016-06-19, 2016-06-20] 的范围完全相同
  • 关于问题 #2,手册指出日期范围是离散的。那么upper 不应该返回2016-06-20 而不是2016-06-21

标签: postgresql postgresql-9.3


【解决方案1】:

关于问题#1:封闭-开放是处理日期范围的标准方法,在学术文献中有 20-25 年的历史。请参阅 Tom Johnston 的 双时态数据 第 24-25 页,以及 Richard Snodgrass 的Developing Time-Oriented Database Applications in SQL

但我认为其中一个原因是连续的范围没有重叠。如果a[May2016, Jun2016) 并且b[Jun2016, Jul2016),它们不会共享任何日期。因此它们“卡在一起”,您不必担心它们接触的边缘情况。

请注意,封闭-开放的一个缺点(可能)是您不能指定空范围。 [May2016, May2016) 只是自相矛盾,而[May2016, May2016] 是瞬间。

关于问题#2:同样,它可能会有所不同,但我可以想到让upper([May2016, Jun2016))返回Jun2016的几个优点:

  • 无论范围的分辨率如何,它都会返回相同的内容。
  • 它更像是开放端点的数学含义,它是唯一可能的答案。
  • 它返回与“标签”匹配的内容,因此可以说它不那么令人惊讶。
  • 它可以让您轻松查看两个范围是否“相遇”:upper(a) = lower(b)

另外,请注意,在 Postgres 中,所有与时间相关的数据类型都是离散的。曾经有一个选项可以使用基于浮点的时间戳来编译 Postgres,但它已被弃用,我从未遇到过。

【讨论】:

  • 感谢您的出色回答。我一定会查看/阅读您列出的资源。
  • 我不会仅仅为了这个而购买任何一本书,但时间数据库的主题非常深刻和迷人。 Snodgrass 书可在此处免费获取:cs.arizona.edu/~rts/publications.html(但更便于阅读印刷版)。
  • 哦,还有:Johnston 在脚注中说,他在另一本书在关系数据库中管理时间,第 56-59 页更全面地介绍了关闭/打开的基本原理.不过我还没读过。
猜你喜欢
  • 1970-01-01
  • 2021-12-30
  • 1970-01-01
  • 1970-01-01
  • 2012-12-25
  • 1970-01-01
  • 1970-01-01
  • 2021-12-20
  • 2011-04-19
相关资源
最近更新 更多