Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1nQCd3-0001pP-Hw for pgsql-sql@arkaria.postgresql.org; Fri, 04 Mar 2022 18:26:14 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1nQCd2-0001DO-9G for pgsql-sql@arkaria.postgresql.org; Fri, 04 Mar 2022 18:26:12 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1nQCd1-0001AI-RC for pgsql-sql@lists.postgresql.org; Fri, 04 Mar 2022 18:26:12 +0000 Received: from forward501j.mail.yandex.net ([5.45.198.251]) by magus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1nQCcx-00038x-GF for pgsql-sql@lists.postgresql.org; Fri, 04 Mar 2022 18:26:11 +0000 Received: from sas8-e0a74b0f546c.qloud-c.yandex.net (sas8-e0a74b0f546c.qloud-c.yandex.net [IPv6:2a02:6b8:c1b:2a0b:0:640:e0a7:4b0f]) by forward501j.mail.yandex.net (Yandex) with ESMTP id D42F8623142; Fri, 4 Mar 2022 21:26:04 +0300 (MSK) Received: from sas8-c6148047b62a.qloud-c.yandex.net (sas8-c6148047b62a.qloud-c.yandex.net [2a02:6b8:c1b:2a11:0:640:c614:8047]) by sas8-e0a74b0f546c.qloud-c.yandex.net (mxback/Yandex) with ESMTP id RceEuZIBYG-Q4gW0p1Q; Fri, 04 Mar 2022 21:26:04 +0300 X-Yandex-Fwd: 2 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yandex.ru; s=mail; t=1646418364; bh=oexVyXEX04mbDxzCFsQbRVo7Kevh13TtRnVmu3va0/0=; h=In-Reply-To:From:Cc:Date:References:To:Subject:Message-ID; b=ZV5jXf3hihfZyrFdkdVb61iAEDTxzruYuf/J/y0FDyBvh3vyLliiLhjuA2WW6GPaZ SoCb+0XxG4KiVA1ep16kOkd+eVndV6ED8oNtv5FVJpFiJA1tvSaOChXWzKl3C/rOoT vkvceGnlbLEFs+ntumGt/mMyXmYwhd6/lVzEneH0= Authentication-Results: sas8-e0a74b0f546c.qloud-c.yandex.net; dkim=pass header.i=@yandex.ru Received: by sas8-c6148047b62a.qloud-c.yandex.net (smtp/Yandex) with ESMTPSA id xFLrex33oY-Q4KiM1FR; Fri, 04 Mar 2022 21:26:04 +0300 (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (Client certificate not present) Subject: Re: unique index with several columns To: "Voillequin, Jean-Marc" , "David G. Johnston" Cc: "pgsql-sql@lists.postgresql.org" References: From: Alexey M Boltenkov Message-ID: <6699c0e9-e358-1fc2-7ce4-7a24d4bc419e@yandex.ru> Date: Fri, 4 Mar 2022 21:26:03 +0300 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0 Thunderbird/52.9.1 MIME-Version: 1.0 In-Reply-To: Content-Type: multipart/alternative; boundary="------------7955F0E3454549E0118B33F0" Content-Language: en-US List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk This is a multi-part message in MIME format. --------------7955F0E3454549E0118B33F0 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit You need the new v15 feature: NULLS [NOT] DISTINCT Specifies whether for a unique index, null values should be considered distinct (not equal). The default is that they are distinct, so that a unique index could contain multiple null values in a column. https://www.postgresql.org/docs/devel/sql-createindex.html On 03/04/22 19:11, Voillequin, Jean-Marc wrote: > > Yes, it helps, thank you. > > But I have many tables with many indexes and many columns! > > Tons of combinations… ☹ > > *From:* David G. Johnston > *Sent:* Friday, March 4, 2022 4:32 PM > *To:* Voillequin, Jean-Marc > *Cc:* pgsql-sql@lists.postgresql.org > *Subject:* Re: unique index with several columns > > *CAUTION:*This email originated from outside of Moody's. Do not click > links or open attachments unless you recognize the sender and know the > content is safe. > > On Fri, Mar 4, 2022 at 8:07 AM Voillequin, Jean-Marc > > wrote: > > When one of the field is null, PG considers that the tuple is not > the same: > > ('a',null) is not equal to ('a',null) > > So, the unique constraint is not violated in PG. > > But is there a way to have the same feature than Oracle? > > I already tried with: > > create unique index idx on t(coalesce(c1,''),coalesce(c2,'')) > > But in this case, I cannot insert several (null,null) without > raising a duplicate key error. > > You just said you wanted nulls to be considered equal to each other... > > Not tested but these should work in conjunction with each other: > > CREATE UNIQUE INDEX idx ON t (c1, c2) WHERE c1 IS NOT NULL AND c2 IS > NOT NULL; > > CREATE UNIQUE INDEX idx2 ON t (c1) WHERE c2 IS NULL AND c1 IS NOT NULL; > > CREATE UNIQUE INDEX idx3 ON t (c2) WHERE c1 IS NULL AND c2 IS NOT NULL; > > --CREATE INDEX idx4 ON t (c1, c2) WHERE c1 IS NULL AND c2 IS NULL; > (pointless...but symmetric with the others) > > Hopefully this helps. > > David J. > > ----------------------------------------- > Moody's monitors email communications through its networks for > regulatory compliance purposes and to protect its customers, employees > and business and where allowed to do so by applicable law. The > information contained in this e-mail message, and any attachment > thereto, is confidential and may not be disclosed without our express > permission. If you are not the intended recipient or an employee or > agent responsible for delivering this message to the intended > recipient, you are hereby notified that you have received this message > in error and that any review, dissemination, distribution or copying > of this message, or any attachment thereto, in whole or in part, is > strictly prohibited. If you have received this message in error, > please immediately notify us by telephone, fax or e-mail and delete > the message and all of its attachments. Every effort is made to keep > our network free from viruses. You should, however, review this e-mail > message, as well as any attachment thereto, for viruses. We take no > responsibility and have no liability for any computer virus which may > be transferred via this e-mail message. > ----------------------------------------- --------------7955F0E3454549E0118B33F0 Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: 8bit
You need the new v15 feature:

NULLS [NOT] DISTINCT
Specifies whether for a unique index, null values should be considered distinct (not equal). The default is that they are distinct, so that a unique index could contain multiple null values in a column.

https://www.postgresql.org/docs/devel/sql-createindex.html


On 03/04/22 19:11, Voillequin, Jean-Marc wrote:

Yes, it helps, thank you.

But I have many tables with many indexes and many columns!

Tons of combinations…

 

From: David G. Johnston <david.g.johnston@gmail.com>
Sent: Friday, March 4, 2022 4:32 PM
To: Voillequin, Jean-Marc <Jean-Marc.Voillequin@moodys.com>
Cc: pgsql-sql@lists.postgresql.org
Subject: Re: unique index with several columns

 

 

CAUTION: This email originated from outside of Moody's. Do not click links or open attachments unless you recognize the sender and know the content is safe.

 

On Fri, Mar 4, 2022 at 8:07 AM Voillequin, Jean-Marc <Jean-Marc.Voillequin@moodys.com> wrote:

 

When one of the field is null, PG considers that the tuple is not the same:

('a',null) is not equal to ('a',null)

So, the unique constraint is not violated in PG.

 

But is there a way to have the same feature than Oracle?

 

I already tried with:

create unique index idx on t(coalesce(c1,''),coalesce(c2,''))

 

But in this case, I cannot insert several (null,null) without raising a duplicate key error.

 

 

You just said you wanted nulls to be considered equal to each other...

 

Not tested but these should work in conjunction with each other:

 

CREATE UNIQUE INDEX idx ON t (c1, c2) WHERE c1 IS NOT NULL AND c2 IS NOT NULL;

CREATE UNIQUE INDEX idx2 ON t (c1) WHERE c2 IS NULL AND c1 IS NOT NULL;

CREATE UNIQUE INDEX idx3 ON t (c2) WHERE c1 IS NULL AND c2 IS NOT NULL;

--CREATE INDEX idx4 ON t (c1, c2) WHERE c1 IS NULL AND c2 IS NULL; (pointless...but symmetric with the others)

 

Hopefully this helps.

 

David J.

 

-----------------------------------------
Moody's monitors email communications through its networks for regulatory compliance purposes and to protect its customers, employees and business and where allowed to do so by applicable law. The information contained in this e-mail message, and any attachment thereto, is confidential and may not be disclosed without our express permission. If you are not the intended recipient or an employee or agent responsible for delivering this message to the intended recipient, you are hereby notified that you have received this message in error and that any review, dissemination, distribution or copying of this message, or any attachment thereto, in whole or in part, is strictly prohibited. If you have received this message in error, please immediately notify us by telephone, fax or e-mail and delete the message and all of its attachments. Every effort is made to keep our network free from viruses. You should, however, review this e-mail message, as well as any attachment thereto, for viruses. We take no responsibility and have no liability for any computer virus which may be transferred via this e-mail message.
-----------------------------------------


--------------7955F0E3454549E0118B33F0--