Postgres有没有办法创建一个引用另一个表中的日期范围的日期外键?

Moh*_*han 4 sql postgresql

假设我们有两个表如下

CREATE TABLE calendar_month (  
  id serial PRIMARY KEY,  
  start_date date NOT NULL,  
  end_date date NOT NULL,  
  reporting_month character varying(50) NOT NULL
);

CREATE TABLE calendar (    
  id serial PRIMARY KEY,  
  holiday bool NOT NULL,  
  actual_date date NOT NULL  
);
Run Code Online (Sandbox Code Playgroud)

如果没有使用触发器,是否有办法确保在日历表中输入的任何actual_date在calendar_month表中始终具有相应的reporting_month,它可以引用?

小智 6

如果你可以改变你的表,你可以用外键和检查约束来做到这一点:

CREATE TABLE calendar_month (  
  id serial PRIMARY KEY, 
  start_date date NOT NULL UNIQUE,  
  end_date date NOT NULL,  
  reporting_month character varying(50) NOT NULL
);

CREATE TABLE calendar (    
  id serial PRIMARY KEY,  
  month_start_date date NOT NULL REFERENCES calendar_month(start_date),
  holiday bool NOT NULL,  
  actual_date date NOT NULL CHECK ( 
    actual_date>=month_start_date and
    actual_date<(month_start_date+'1 month'::interval)::date)
);
Run Code Online (Sandbox Code Playgroud)

编辑:Mohan已经说过"日历行中的end_date不一定是= start_date + 1个月的间隔".假设我们不能对这几个月的实际sart和结束日期做出任何假设,我们必须稍微做一些事情(正如Mohan自己建议的那样):

CREATE TABLE calendar_month (  
  id serial PRIMARY KEY, 
  start_date date NOT NULL,  
  end_date date NOT NULL,  
  reporting_month character varying(50) NOT NULL,
  UNIQUE(start_date, end_date)
);

CREATE TABLE calendar (    
  id serial PRIMARY KEY,  
  month_start_date date NOT NULL,
  month_end_date date NOT NULL,
  holiday bool NOT NULL,
  foreign key(month_start_date, month_end_date) 
    REFERENCES calendar_month(start_date, end_date) )  
  actual_date date NOT NULL 
    CHECK (actual_date>=month_start_date and actual_date<month_end_date)
);
Run Code Online (Sandbox Code Playgroud)

或者也许actual_date<month_end_date应该actual_date<=month_end_datecheck约束中 - 这取决于您如何定义月份界限.


OMG*_*ies 1

不:

  • 外键不提供在比较之前更改数据类型的功能
  • 检查约束仅适用于同一个表,不适用于任何其他表

根据提供的 CREATE TABLE 语句,触发器是您唯一的选择。