Reputation: 5940
I am learning postgresql and I have created 2 tables: goals
and results
. Each table has a primary key which is formed by 3 columns:
I did this so that each row must be unique not only by its id but also depending on when the goal or result is still valid. Here is my sql code:
CREATE TABLE goals (
goal_id INT,
goal_title VARCHAR(80),
goal_description VARCHAR(300),
goal_valid_from_date TIMESTAMP,
goal_valid_until_date TIMESTAMP,
goal_deleted_flag BOOLEAN,
PRIMARY KEY (goal_id, goal_valid_from_date, goal_valid_until_date)
);
CREATE TABLE results (
result_id INT,
goal_id INT,
result_description VARCHAR(300),
result_target FLOAT,
result_timestamp DATE,
result_valid_from_date TIMESTAMP,
result_valid_until_date TIMESTAMP,
result_deleted_flag BOOLEAN,
PRIMARY KEY (result_id, result_valid_from_date, result_valid_until_date)
);
My goal now is to create a foreign key so that I am able to connect the 2 tables based on the goal_id
column only and not the valid_from/until_date
columns otherwise they would never match.
I tried to achieve this by using the following lines of code:
ALTER TABLE results
ADD FOREIGN KEY(goal_id)
REFERENCES goals(goal_id) on delete set null;
However I get an error:
SQL Error [42830]: ERROR: there is no unique constraint matching given keys for referenced table "goal"
Would you be able to propose a smart and elegant way to achieve my goal?
Upvotes: 0
Views: 984
Reputation: 592
it is very clear in the documentation
FOREIGN KEY ( column_name [, ... ] ) REFERENCES reftable [ ( refcolumn [, ... ] ) ]
you need to put the list of column_name
Upvotes: 2
Reputation: 3469
... so that I am able to connect the 2 tables based on the goal_id column only ...
As the error message already suggests, you need to add a matching UNIQUE CONSTRAINT:
ALTER TABLE goals
ADD CONSTRAINT u_goals_goal_id
UNIQUE (goal_id)
However, this constraint is more restrictive than your actual primary key, which might not be what you want, if your current design is on purpose and not by accident (see the comments of @MikeOrganek and @ErwinBrandstetter).
If it is what you want then you should consider making this your primary key instead.
For your exclusion problem (no two goals may have overlapping time periods) take a look at the example in the manual, it literally describes your case.
Upvotes: 2