Postgres LIKE唯一约束可能吗?

时间:2013-05-30 17:29:55

标签: postgresql unique-constraint

我是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;

2 个答案:

答案 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

如果您在时区"之后尝试施放"然后它真的是不可变的,你可以有你的约束。

当然另一种选择是将强制转换包装在函数中并将函数标记为不可变。如果您不想这样对系统撒谎,那么当您的数据库从现在起一年后出现奇怪的行为时,请不要抱怨。