将整型范围排序为PostgreSQL日期范围
因为PostgreSQL中的BC日期仅止于公元前4713年,我一般不想限制BC日期,所以我决定使用int作为日期 这是我做了将整型范围排序为PostgreSQL日期范围,postgresql,sorting,date,integer,range,Postgresql,Sorting,Date,Integer,Range,因为PostgreSQL中的BC日期仅止于公元前4713年,我一般不想限制BC日期,所以我决定使用int作为日期 这是我做了select*fromtestorderbydaterange之后的表: id daterange 26 [-6000501,-6000301) 27 [-6000401,-6000201) 22 [-4001202,-4000102) 23 [-4000702,-4000302) 19 [-3010102,-3000102) 21 [-3001202,-30
select*fromtestorderbydaterange之后的表代码>:
id daterange
26 [-6000501,-6000301)
27 [-6000401,-6000201)
22 [-4001202,-4000102)
23 [-4000702,-4000302)
19 [-3010102,-3000102)
21 [-3001202,-3000102)
14 [-3001011,-2000101)
15 [-1000506,6000701)
20 [3000102,3001201)
16 [12500709,13650230)
17 [14580102,16590507)
存在表示按时间顺序排列的年代的整数范围。负数是BC日期。模式为YYYYMMDD
问题是ID27[-600041,-6000201)
应该是第一个,而ID26应该是第一个[-600051,-6000301)
第二,因为BC日期是颠倒的:上界是按时间顺序排列的第一位。此外,一年中的月份不会下降,而是上升。但是PostgreSQL尝试保存负数,而不知道按时间顺序排列的内容。因此它们应该按如下顺序排列:
-6000201,然后是600041(公元前600年2月,然后是4月)
-6000301,然后是600051(公元前600年三月,然后是五月)
因此:
id 27 [-6000401,-6000201) -- first
id 26 [-6000501,-6000301) -- second
明确地说,我不想在范围内切换边界-这是不可能的。我想按照最大边界翻转排序顺序,就像上面一样。我不知道如何对此类范围进行排序。它应该根据它们的上限对它们进行排序,DESC
我想?我尝试了类似的方法
SELECT * FROM test
ORDER BY daterange ASC
, CASE WHEN (upper(daterange)<0) AND (lower(daterange)<0) THEN daterange END DESC;
从测试中选择*
按日期范围ASC排序
,CASE WHEN(上(日期范围)PostgreSQLdate
类型确实限于公元前4713年。但它可以达到公元前5874897年——将近600万年
我希望您不需要将日期存储在所有600万年的范围内。您可以做的是将日期添加到100万年(或两年)的范围内,这样您就可以适应PostgreSQL支持的范围。只要想想您已经更改了日期
例如,您可以存储999400-02-01 AD
(+1'000'000年),而不是600-02-01 BC
您可以从int4range
切换到daterange
。您将免费获得适当的排序
您需要记住的是,在显示日期之前,先减去已添加的年份。在使用创造性的日期格式时,这应该达到正确的升序排序顺序:
SELECT *
, upper(daterange), upper(daterange)/10000, upper(daterange)%10000
, lower(daterange), lower(daterange)/10000, lower(daterange)%10000
FROM test
ORDER BY CASE WHEN upper(daterange) >= 0 THEN daterange END NULLS FIRST
-- BC before AD, fully sort AD
, upper(daterange)/10000 -- BC by start year
, upper(daterange)%10000 DESC -- BC by start date
, lower(daterange)/10000 -- BC by end year
, lower(daterange)%10000 DESC; -- BC by end date
小提琴
对于BC日期,CASE
表达式默认为NULL
,并且这些日期首先排序(没有进一步区分)。关于NULLS first
:
接下来的4个表达式根据您的规则对BC日期进行排序。您可以在每个表达式中添加大小写(日期范围)<0
,但由于广告日期已经完全排序,所以不会有什么区别。可能是为了性能,但不会太多。@ErwinBrandstetter谢谢您提供的提示,编辑了我的问题。您有什么答案吗?