CREATE TABLE foo ( dt AS DATE NOT NULL, type AS TEXT NOT NULL, CONSTRAINT unique_dt_type UNIQUE(dt,type) -- check constraint(?) )
Having a brain-dud when trying to think of the right syntax to create a unique constraint when only a certain condition exists.
Given, type
can have values A-F
, there can only be one A
per date, but there can be multiple B-F
. Example of good table:
2010-01-02 | 'A' -- only one 2010-01-02 | 'B' -- can have multiple 2010-01-02 | 'B' 2010-01-02 | 'B' 2010-01-02 | 'C' -- can have multiple 2013-01-02 | 'A' -- only one 2010-01-02 | 'B' -- can have multiple 2010-01-02 | 'B' 2013-01-02 | 'F' -- can have multiple 2013-01-02 | 'F'
Tried reading check/unique syntax but there weren't any examples. CHECK
came close but only limited it to a range and wasn't used in conjunction with a UNIQUE
scenario. Also tried searching, but my search skills are either not up to par, or there aren't any similar questions.
The UNIQUE constraint ensures that all values in a column are different. Both the UNIQUE and PRIMARY KEY constraints provide a guarantee for uniqueness for a column or set of columns. A PRIMARY KEY constraint automatically has a UNIQUE constraint.
Which SQL constraint do we use to set some value to a field whose value has not been added explicitly? Explanation: The DEFAULT constraint is used to set a default value for a column which comes into use when a value for a field in that column is not set.
To create a unique constraintOn the Table Designer menu, select Indexes/Keys. In the Indexes/Keys dialog box, select Add. In the grid under General, select Type and choose Unique Key from the drop-down list box to the right of the property, and then select Close.
You can insert NULL values into columns with the UNIQUE constraint because NULL is the absence of a value, so it is never equal to other NULL values and not considered a duplicate value. This means that it's possible to insert rows that appear to be duplicates if one of the values is NULL .
PostgreSQL can address your needs via it's "Partial Index" feature. In practice this is accomplished by adding a where clause to the create index statement.
Sample:
CREATE INDEX my_partial_ix ON my_sample_table (my_sample_field) WHERE (my_sample_field = 'rows to index');
Take a look here: http://www.postgresql.org/docs/current/interactive/indexes-partial.html
Pay particular attention to the section Example 11-3. Setting up a Partial Unique Index
. It gives an example that lines up well with your stated objective.
CREATE UNIQUE INDEX my_partial_ix ON my_sample_table (my_sample_field) WHERE NOT (my_sample_field = 'duplicates ok');
Using a trigger:
CREATE OR REPLACE FUNCTION "CheckConstraint"() RETURNS trigger AS $BODY$declare already_exists boolean; begin if new.foo_type='A' then select count(*) >0 from foo where foo_type='A' and dt=new.dt INTO already_exists; if already_exists then raise exception 'date % already have an A', new.dt; end if; end if; return new; end;$BODY$ LANGUAGE plpgsql VOLATILE COST 100;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With