Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/10.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中处理周末和节假日的最佳方式_Sql_Postgresql - Fatal编程技术网

在postgresql中处理周末和节假日的最佳方式

在postgresql中处理周末和节假日的最佳方式,sql,postgresql,Sql,Postgresql,我有一个数据库,其中包含一个sell表。此销售表包含一个带有销售日期的列。我的问题是:我只想在搜索中显示工作日 该表简化如下: # select * from sells; id | emission ----+------------ 1 | 2019-11-19 2 | 2019-11-20 3 | 2019-11-21 4 | 2019-11-23 5 | 2019-11-24 6 | 2019-11-25 7 | 2019-11-22 (7 rows)

我有一个数据库,其中包含一个sell表。此销售表包含一个带有销售日期的列。我的问题是:我只想在搜索中显示工作日

该表简化如下:

# select * from sells;
 id |  emission  
----+------------
  1 | 2019-11-19
  2 | 2019-11-20
  3 | 2019-11-21
  4 | 2019-11-23
  5 | 2019-11-24
  6 | 2019-11-25
  7 | 2019-11-22
(7 rows)
我还有一张有假期的桌子:

postgres=# select * from holidays;
 id |  holiday   
----+------------
  1 | 2019-11-20
  2 | 2019-11-22
(2 rows)
CREATE TABLE holiday (holiday date, name varchar, next_workday date) 
事实上,我只需要做以下工作来获得工作日:

    SELECT sells.id,
           EXTRACT(DOW FROM emission), 
           CASE WHEN EXTRACT(DOW FROM emission)=6 
                THEN emission+'2 days'::interval 
                WHEN EXTRACT(DOW FROM emission)=0 
                THEN emission+'1 day'::interval 
                WHEN holiday is not null
                THEN emission+'1 day'::interval
                ELSE emission
            END
     FROM sells
LEFT JOIN holidays ON (holiday=emission);

 id | date_part |      emission       
----+-----------+---------------------
  1 |         2 | 2019-11-19 00:00:00
  2 |         3 | 2019-11-21 00:00:00
  3 |         4 | 2019-11-21 00:00:00
  7 |         5 | 2019-11-23 00:00:00
  4 |         6 | 2019-11-25 00:00:00
  5 |         0 | 2019-11-25 00:00:00
  6 |         1 | 2019-11-25 00:00:00
(7 rows)
关于这种方法有两个问题:

  • 如果假日在星期五,下一个日期是星期六,那么这是一个问题,如上次查询的
    id=7
    所示

  • 优化。Sales表有500万行,在本例中,我们遇到了性能问题。我相信,在这种方法中添加索引是行不通的,因为在
    CASE
    语句中使用了两个表

  • 一个选项是使用默认触发器创建一个新列,生成正确的日期,但是,如果新假日添加到假日表中

    我正在ubuntu中使用postgresql-10。仓库中的数据由apache Kafka中的接收器连接器提供(如果需要,可以在表中添加新列。

    解决方案(由@a_horse_建议,注释中没有名称:)

    我创建了一个表“假日”:

    创建了一个未来27年的insert语句(在internet上找到了当地假日的列表-我希望每个国家都有自己的假日,因此,需要为每个国家创建一个特定的列表),在此之前,运行此查询(周六和周日视为周末,另一种情况可能因国家而异)

    并且,修改了主选择:

    SELECT sells.id,
               EXTRACT(DOW FROM COALESCE(next_workday, emission)), 
               CASE WHEN EXTRACT(DOW FROM COALESCE(next_workday, emission))=6 
                    THEN emission+'2 days'::interval 
                    WHEN EXTRACT(DOW FROM COALESCE(next_workday, emission))=0 
                    THEN emission+'1 day'::interval 
                    ELSE COALESCE(next_workday, emission)
                END
         FROM sells
    LEFT JOIN holidays ON (holiday=emission);
    

    我认为最简单的解决方案是创建一个日历表,其中包含未来10年内每天的一行。然后,您可以将每一行标记为假日或工作日(请注意,“工作日”在世界范围内从周一到周五都不是必需的),并且您可以在其中包含一列“第二天”对于每一种情况。计算10年一次并不难,甚至可以使用过程代码来完成。但是使用过程代码可以让查询变得非常简单-你只需在日期加入即可。我认为你的
    更新
    语句需要周五(道琼斯指数=5)完成+3天,周六(道琼斯指数=6)在美国,这不是问题,除非感恩节后一天被视为公司假日。在其他国家,可能是复活节,例如丹麦,复活节是周四、周五和周一,所以从周四开始+5。
    
    SELECT sells.id,
               EXTRACT(DOW FROM COALESCE(next_workday, emission)), 
               CASE WHEN EXTRACT(DOW FROM COALESCE(next_workday, emission))=6 
                    THEN emission+'2 days'::interval 
                    WHEN EXTRACT(DOW FROM COALESCE(next_workday, emission))=0 
                    THEN emission+'1 day'::interval 
                    ELSE COALESCE(next_workday, emission)
                END
         FROM sells
    LEFT JOIN holidays ON (holiday=emission);