2013-05-30 64 views
1

我是Postgres的新用戶,正在使用pgAdmin III創建表(metrics_reaches)。Postgres LIKE唯一約束可能嗎?

在我的表中,我有一個insertion_timestamp時間戳與時間編排類型列。

我想創建一個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; 

回答

1

嘗試CAST():

CONSTRAINT metrics_reaches_organizations_id_key UNIQUE (
    organizations_id, 
    applications_id, 
    countries_id, 
    platforms_id, 
    CAST(insertion_timestamp AS date) 
) 
+0

對弗蘭克的回答評論不適合在這裏,因此發佈爲單獨的答案。 –

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 

如果嘗試申請後施放「在時間區」,那麼它確實是不變的,你可以有你的約束。

當然,其他選項是將轉換包裝在一個函數中,並將該函數標記爲不可變。如果你要這樣對系統撒謊,不要抱怨當你的數據庫從現在起每年表現異常。