Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将整型范围排序为PostgreSQL日期范围_Postgresql_Sorting_Date_Integer_Range - Fatal编程技术网

将整型范围排序为PostgreSQL日期范围

将整型范围排序为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

因为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,-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(上(日期范围)PostgreSQL
    date
    类型确实限于公元前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谢谢您提供的提示,编辑了我的问题。您有什么答案吗?