我是Postgres的新手,正在使用pgAdmin III创建一个表(metrics_reaches
)。
在我的表格中,我有insertion_timestamp
时间戳与timezome 类型列。
我想创建一个UNIQUE
约束,除其他字段外,它只会检查insertion_timestamp
的日期部分,而不是时间。
有办法吗?这是我的脚本目前的样子(见最后CONSTRAINT
)。
-- Table: metrics_reaches
-- DROP TABLE metrics_reaches;
CREATE TABLE metrics_reaches
(
organizations_id integer NOT NULL,
applications_id integer NOT NULL,
countries_id integer NOT NULL,
platforms_id integer NOT NULL,
...
insertion_timestamp timestamp with time zone NOT NULL,
id serial NOT NULL,
CONSTRAINT metrics_reaches_pkey PRIMARY KEY (id),
CONSTRAINT metrics_reaches_applications_id_fkey FOREIGN KEY (applications_id)
REFERENCES applications (id) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE CASCADE,
CONSTRAINT metrics_reaches_countries_id_fkey FOREIGN KEY (countries_id)
REFERENCES countries (id) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE CASCADE,
CONSTRAINT metrics_reaches_organizations_id_fkey FOREIGN KEY (organizations_id)
REFERENCES organizations (id) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE CASCADE,
CONSTRAINT metrics_reaches_platforms_id_fkey FOREIGN KEY (platforms_id)
REFERENCES platforms (id) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE CASCADE,
CONSTRAINT metrics_reaches_organizations_id_key UNIQUE (organizations_id, applications_id, countries_id, platforms_id, insertion_timestamp)
)
WITH (
OIDS=FALSE
);
ALTER TABLE metrics_reaches
OWNER TO postgres;
答案 0 :(得分:1)
尝试CAST():
CONSTRAINT metrics_reaches_organizations_id_key UNIQUE (
organizations_id,
applications_id,
countries_id,
platforms_id,
CAST(insertion_timestamp AS date)
)
答案 1 :(得分:1)
这实际上是对弗兰克答案的评论,但评论框的时间太长了。
如果你是偏执狂,你需要在处理日期演员时仔细观察当地时区:
bookings=> SET timezone='GMT';
SET
bookings=> SELECT now() at time zone 'GMT', (now() at time zone 'GMT')::date, now(), now()::date;
timezone | timezone | now | now
---------------------------+------------+------------------------------+------------
2013-05-30 19:36:04.23684 | 2013-05-30 | 2013-05-30 19:36:04.23684+00 | 2013-05-30
(1 row)
bookings=> set timezone='GMT-7';
SET
bookings=> SELECT now() at time zone 'GMT', (now() at time zone 'GMT')::date, now(), now()::date;
timezone | timezone | now | now
----------------------------+------------+-------------------------------+------------
2013-05-30 19:36:13.723558 | 2013-05-30 | 2013-05-31 02:36:13.723558+07 | 2013-05-31
现在,PG很聪明,知道这是一个问题,如果你尝试使用日期转换创建一个约束,那么你应该看到类似的东西:
ERROR: functions in index expression must be marked IMMUTABLE
如果您在时区"之后尝试施放"然后它真的是不可变的,你可以有你的约束。
当然另一种选择是将强制转换包装在函数中并将函数标记为不可变。如果您不想这样对系统撒谎,那么当您的数据库从现在起一年后出现奇怪的行为时,请不要抱怨。