考虑我的模式:
CREATE TABLE t_date (
t_date_id int PRIMARY KEY
, valid_from date NOT NULL
, valid_to date DEFAULT 'infinity'
);
有时我会 valid_to
约会,有时我有 infinity
在那里。。。
如何正确过滤以获得范围最短的行?
我试过:
(DATE_PART('day', valid_to::timestamp - valid_from::timestamp))
但结果是:
PG::DatetimeFieldOverflow: ERROR: cannot subtract infinite timestamps`
我有筛选器来选择有效范围: valid_from <= ? AND valid_to > ?
其思想是以最短的范围获取(一)个有效行。
示例
INSERT INTO t_date VALUES
(1, '2020-01-01', '2020-09-01')
, (2, '2020-01-10', '2020-01-12')
, (3, '2020-01-15', 'INFINITY')
, (4, '2020-01-16', 'INFINITY') -- shortest among infinities
, (5, '2020-01-14', 'INFINITY')
;
如果今天是 11/jan
我希望得到 '2020-01-10' | '2020-01-12'
因为有效期是1月11日,最短的。
如果今天是 14/jan
我希望得到 '2020-01-01' | '2020-09-01'
因为它的有效期是1月14日和最短的。
如果今天是 17/jan
我希望得到 '2020-01-16' | 'INFINITY'
.
如果后来我创造了 '2020-01-15' | '2059-01-15'
,应该返回,因为它比无限行短。
1条答案
按热度按时间qacovj5a1#
db<>在这里摆弄
NULLIF()
皈依者'infinity'
至NULL
,所以整个表达式变成NULL
,默认情况下最后排序ASCENDING
命令。无限范围应该排在你任务的最后。要打破无限范围之间的联系,请另外按
valid_from DESC
-定义了什么NOT NULL
所以我们不需要特殊的治疗NULL
案例。作为一个(欢迎?)副作用,这也打破了其他长度相等的范围之间的联系,选择了最新的开始。为了得到确定的结果,如果允许相同的范围,您可能需要添加另一个明确的tiebreaker(如pk列)。
相关:
将空值排序到表的末尾