Can I have a foreign key constraint that takes a timestamp column but uses it as date only?
I'm trying something like this but it doesn't work:
alter table table1 add constraint my_constraint foreign key ( date(created_date) ) references table2( date(transaction_timestamp) );- 2You can't create a foreign key constraint on express
date(created_date). foreign key constraint must have reference columns.Kamran– Kamran2025-08-08 11:48:44 +00:00CommentedAug 8 at 11:48 - 1You can use triggers instead of an FK.Panagiotis Kanavos– Panagiotis Kanavos2025-08-08 11:59:47 +00:00CommentedAug 8 at 11:59
- Please add examples showing what you'd expect this to do.Vérace'snot-taking-a-no-for-an-answer take, while commendable, limits this to 1 timezone and 1 transaction a day, mainly because FK's need a
uniqueindex. My guess is you're trying to stoptable1rows without at least 1 existing transaction on the same date intable2- in that case @PanagiotisKanavos' comment above is closer to what you'd realistically want, suggesting aconstraint triggerthat runs aselect exists. Unless you clarify, there's too much room for interpretationZegarek– Zegarek2025-08-11 21:47:05 +00:00CommentedAug 11 at 21:47
2 Answers2
Despite what everyone else is saying, you can do this! But you have to "cheat" (a little! :-) )!
I did the following - this is the "cheating" bit!. All of the code below can be found on the fiddlehere.
CREATE OR REPLACE FUNCTION Get_Date(tz TIMESTAMPTZ)RETURNS DATEAS $$ SELECT $1::DATE $$LANGUAGE SQL IMMUTABLE;Youhave to be sure of the consequences here - the mutability is to do with timezones &c. You could potentially have issues with time/date errors here - but if you're prepared to take this risk or you only ever work in one timezone, thencaveat emptor! :-)
and then the following:
CREATE TABLE t ( ttz TIMESTAMPTZ PRIMARY KEY, ttzd_gen DATE UNIQUE GENERATED ALWAYS AS (Get_Date(ttz)) STORED);and the child table:
CREATE TABLE u( utz TIMESTAMPTZ, utzd_gen DATE GENERATED ALWAYS AS (Get_Date(utz)) STORED, CONSTRAINT utztz_gen_fk FOREIGN KEY (utzd_gen) REFERENCES t(ttzd_gen));and now we insert a record in the parent:
INSERT INTO t VALUES (NOW());and everything is fine and dandy! Insert into the child:
INSERT INTO u VALUES (NOW());again, fine and dandy!
But:
INSERT INTO u VALUES (NOW() + INTERVAL '1 DAY');and wallop!
ERROR: insert or update on table "u" violates foreign key constraint "utztz_gen_fk"DETAIL: Key (utzd_gen)=(2025-08-09) is not present in table "t".Our desired result.
I'm not quite surewhy you want to do this, but it can be done! You'll only be able to have one day per year? You can check out posts by Erwin Brandstetter on this topic!
4 Comments
datestyle. See my example here:stackoverflow.com/a/79699962/20860datestyle - thanks for pointing that out! I did mention the possibility ofould potentially have issues with time/date errors here - but it's good to coverall the bases!No — you can’t directly create a foreign key constraint on an expression like DATE(created_date) in standard SQL (including MySQL, PostgreSQL, SQL Server, Oracle, etc.).
Foreign key constraints must be defined between actual columns, not computed expressions. Both columns must also match in data type and precision.
2 Comments
A foreign key must reference columns that either are a primary key or form a unique constraint, or are columns from a non-partial unique index. If your expression points to a unique value of the same data type, you're fine. Seepostgresql.org/docs/current/…Explore related questions
See similar questions with these tags.




