Обсуждение: Can I CONSTRAIN a particular value to be UNIQUE?

Поиск
Список
Период
Сортировка

Can I CONSTRAIN a particular value to be UNIQUE?

От
reina@nsi.edu (Tony Reina)
Дата:
I have a table where I'd like to store only one instance where a trial
was successful, but all instances where the trial failed. The success
or failure is indicated by the field called 'success'. There should be
only one unique case for each trial where success = 1, but an
undefined number of cases where success = 0.

e.g. 
CREATE TABLE table_1 (
subject    text,
target     int2,
trial      int4,
success    int2,
data       float4 );

CREATE UNIQUE INDEX pktable_1 ON table_1 (subject, target, trial);

I'd like to have some way for SQL to give me an error if I attempt to
insert more than one instance of a given subject, target, and trial
where success = 1, but would allow me to insert as many instances of
the same subject, target, and trial where success = 0.

Is there a way to do this at table creation time?

Thanks.
-Tony


Re: Can I CONSTRAIN a particular value to be UNIQUE?

От
Stephan Szabo
Дата:
On 29 Nov 2001, Tony Reina wrote:

> I have a table where I'd like to store only one instance where a trial
> was successful, but all instances where the trial failed. The success
> or failure is indicated by the field called 'success'. There should be
> only one unique case for each trial where success = 1, but an
> undefined number of cases where success = 0.
>
> e.g.
> CREATE TABLE table_1 (
> subject    text,
> target     int2,
> trial      int4,
> success    int2,
> data       float4 );
>
> CREATE UNIQUE INDEX pktable_1 ON table_1 (subject, target, trial);
>
> I'd like to have some way for SQL to give me an error if I attempt to
> insert more than one instance of a given subject, target, and trial
> where success = 1, but would allow me to insert as many instances of
> the same subject, target, and trial where success = 0.
>
> Is there a way to do this at table creation time?

Not really within what we provide (theoretically you could probably do
it with a subselect in check I think). You'll probably will want to look
at writing a plpgsql trigger to do the check.



Re: Can I CONSTRAIN a particular value to be UNIQUE?

От
"G. Anthony Reina"
Дата:
Stephan Szabo wrote:

> Not really within what we provide (theoretically you could probably do
> it with a subselect in check I think). You'll probably will want to look
> at writing a plpgsql trigger to do the check.

Yes, I was hoping that something like CHECK or perhaps a RULE would work,
but it appears that the easiest way may be using an external program.

Thanks Stephan.
-Tony




Re: Can I CONSTRAIN a particular value to be UNIQUE?

От
"G. Anthony Reina"
Дата:
Tom Lane wrote:

> 2. In PG 7.2, partial indexes work again, so you could do
>
>         CREATE UNIQUE INDEX ... (subject, target, trial) WHERE success = 1;
>
> Which of these is better depends on how many of each sort of row
> you expect to have, and whether you'll be doing any queries wherein
> you could use an index on subject/target/trial for the non-success
> rows.
>

Oooooo! Option #2 seems very nice for what I'm trying to do. Would there be
any problem with me using

CREATE UNIQUE INDEX pk1 ON table1 (subject, target, trial) WHERE success = 1;
CREATE UNIQUE INDEX pk0 ON table1 (subject, target, trial) WHERE success = 0;

i.e. 2 partial indicies on the same table?


I know PG7.2 is still in beta, but it might be worthwhile for me to make the
jump from 7.1.3 for this feature. If I upgrade to the beta, will I have to do
a dump/restore again when the official 7.2 release comes out? I know I'll have
to do one for the beta anyway, but I'd hate to have to do it twice (especially
since the 7.2 official release will probably come out soon).

Thanks Tom.
-Tony




Re: Can I CONSTRAIN a particular value to be UNIQUE?

От
Tom Lane
Дата:
reina@nsi.edu (Tony Reina) writes:
> I'd like to have some way for SQL to give me an error if I attempt to
> insert more than one instance of a given subject, target, and trial
> where success = 1, but would allow me to insert as many instances of
> the same subject, target, and trial where success = 0.

Two possibilities:

1. If you're not wedded to that particular data representation, consider  making the success values 1 and NULL not 1
and0.  Then a unique  index across all four columns would act as you desire.
 

2. In PG 7.2, partial indexes work again, so you could do
CREATE UNIQUE INDEX ... (subject, target, trial) WHERE success = 1;

Which of these is better depends on how many of each sort of row
you expect to have, and whether you'll be doing any queries wherein
you could use an index on subject/target/trial for the non-success
rows.
        regards, tom lane


Re: Can I CONSTRAIN a particular value to be UNIQUE?

От
Tom Lane
Дата:
"G. Anthony Reina" <reina@nsi.edu> writes:
> Oooooo! Option #2 seems very nice for what I'm trying to do. Would there be
> any problem with me using

> CREATE UNIQUE INDEX pk1 ON table1 (subject, target, trial) WHERE success = 1;
> CREATE UNIQUE INDEX pk0 ON table1 (subject, target, trial) WHERE success = 0;

> i.e. 2 partial indicies on the same table?

Not at all, but if those are the only two possible values of "success"
then it would seem this is the same as one non-partial unique index.
If you're thinking of allowing other, unconstrained success values then
this could make sense.

> I know PG7.2 is still in beta, but it might be worthwhile for me to make the
> jump from 7.1.3 for this feature. If I upgrade to the beta, will I have to do
> a dump/restore again when the official 7.2 release comes out?

We try to avoid forcing initdb after we start the beta cycle, but we
make no guarantees until we go final.  FWIW, at this point I doubt we'll
need to do that.
        regards, tom lane


Re: Can I CONSTRAIN a particular value to be UNIQUE?

От
"Christopher Kings-Lynne"
Дата:
If you use NULL instead of 0 for the value of success, then there is no
problem:

est=# create table x (a int4, b int4, unique(a,b));
NOTICE:  CREATE TABLE/UNIQUE will create implicit index 'x_a_key' for table
'x'
CREATE
test=# insert into x values (1, NULL);
INSERT 2829459 1
test=# insert into x values (1, NULL);
INSERT 2829460 1
test=# insert into x values (1, NULL);
INSERT 2829461 1
test=# select * from x;a | b
---+---1 |1 |1 |
(3 rows)

Cheers,

Chris

> -----Original Message-----
> From: pgsql-sql-owner@postgresql.org
> [mailto:pgsql-sql-owner@postgresql.org]On Behalf Of Tony Reina
> Sent: Friday, 30 November 2001 3:01 AM
> To: pgsql-sql@postgresql.org
> Subject: [SQL] Can I CONSTRAIN a particular value to be UNIQUE?
>
>
> I have a table where I'd like to store only one instance where a trial
> was successful, but all instances where the trial failed. The success
> or failure is indicated by the field called 'success'. There should be
> only one unique case for each trial where success = 1, but an
> undefined number of cases where success = 0.
>
> e.g.
> CREATE TABLE table_1 (
> subject    text,
> target     int2,
> trial      int4,
> success    int2,
> data       float4 );
>
> CREATE UNIQUE INDEX pktable_1 ON table_1 (subject, target, trial);
>
> I'd like to have some way for SQL to give me an error if I attempt to
> insert more than one instance of a given subject, target, and trial
> where success = 1, but would allow me to insert as many instances of
> the same subject, target, and trial where success = 0.
>
> Is there a way to do this at table creation time?
>
> Thanks.
> -Tony
>
> ---------------------------(end of broadcast)---------------------------
> TIP 3: if posting/reading through Usenet, please send an appropriate
> subscribe-nomail command to majordomo@postgresql.org so that your
> message can get through to the mailing list cleanly
>