2011-10-13 28 views
6

Ben postgres bu gibi satırlar var:null değeri benzersiz değil

create test (
name varchar(10), 
address varchar(20), 
college varchar(20), 
constraint test_uq unique (name,address,college); 

nasıl boş değerlerinin benzersiz hale yapabilirsiniz, bu nedenle çıkış:

name | address | college 

john | rome | 
john | rome | 
max | tokyo | 

Böyle bir tablo oluşturmak şöyle olabilir:

name | address | college 

john | rome | 
max | tokyo | 
+0

MySQL ve benzersiz olmayan null'lerle ilgili soru: http://stackoverflow.com/qu estions/4081783/unique-key-with-nulls – osa

cevap

2

Postgres belgeleri bu davranış, SQL standardı ile uyumlu olduğunu claims: Genel olarak

tabloda iki veya daha fazla satır varken, benzersiz kısıtlama ihlal nerede sütunların tümünü değerleri 'da bulunan kısıtlama eşittir. Ancak, bu karşılaştırmada iki boş değer olarak kabul edilmez. Bu, benzersiz bir kısıtlamasının varlığında bile, kısıtlı sütunlardan en az birinde bir boş değeri içeren yinelenen satırların saklanmasının mümkün olduğu anlamına gelir. Bu davranış SQL standardı ile uyumludur [.]

Bir olasılık da şema yeniden gözden geçirmek (dürüst olmak gerekirse, name+address+college üzerinde benzersizlik kısıtlaması sizin örnekte anlamda bir bütün sürü yapmaz).

+0

oh my..so null değeri benzersiz değil mi? böylelikle kaçınma verilerini nasıl önleyebiliriz? Gerçek tablomda , bu tabloya benzersiz kısıtlama doğru olan tabloya kayıt eklemek, daha sonra aynı rekoru tekrar eklemek ve tabloya aynı rekoru ekledi, sonunda o tabloda 2 aynı kayıt var :( –

0

Benzersiz bir kısıtlama yerine birincil anahtar yaparsanız, çalışır. Bunun için, college numaralı sütunun NOT NULL olması ve (örneğin) boş dizeleri NULL değerleri yerine kullanması gerekir. Yoksa bir sorgu mu arıyorsunuz?

+0

Ben birincil veri yapamayız, çünkü gerçek verilerimde, birkaç kaydın bir değeri vardır, –

+0

Tamam, bazı kayıtlar bir değere sahip olsa bile. 2 kaydın aynı (isim, adres, kolej) değerlere sahip olmamasını istersiniz, değil mi? –

+0

evet doğru, ad, adres, kolej –

0

NULL bilinmiyor, NULL'a eşit NULL değeri asla doğru olamaz. Bu yasayı çözmek için bunu yapın.

Kolejler için yeni bir görünüm tablosu oluşturun. Bu tabloda, None değerine sahip bir kayıt var. Ardından yeni üniversite arama tablosuna bir Yabancı Anahtar koyun.

Bu, sözde koddur, dolayısıyla çalışmasını sağlamak için bununla karıştırmanız gerekebilir, ancak işte temel fikir.

CREATE TABLE college(college_id SERIAL PRIMARY KEY,college_type); 
INSERT INTO college(college_type) 
SELECT 1,None; 


create test (
name varchar(10), 
address varchar(20), 
college_id INTEGER NOT NULL DEFAULT 1, 
constraint test_uq unique (name,address,college_id); 
+0

hmm Ben 2 tablo haline getirmek istemiyorum çünkü benim gerçek verilerimde, 1 tablo yapmak zorundayım çünkü verilerimin amacı bir summary_report. ama cevabınız için teşekkür ederim.Çok teşekkür ederim –

+0

Yine de söylediklerimi yapabilir ama yeni tabloyu bırakabilir ve NULL COLLEGE veya NA – Kuberchaun

+0

ile mevcut kolej tablosundaki NULL yerine üniversiteye varsayılan değeri veririm, o zaman kolej kısıtını boş vermemelisiniz? –

2

sadece bir conditional unique index

 
postgres=# CREATE UNIQUE INDEX test_index ON test (name, address) WHERE college IS NULL; 
CREATE INDEX 
postgres=# INSERT INTO test (name, address) VALUES ('john', 'rome'); 
INSERT 0 1 
postgres=# INSERT INTO test (name, address) VALUES ('max', 'tokyo'); 
INSERT 0 1 
postgres=# INSERT INTO test (name, address, college) VALUES ('john', 'rome', 'college'); 
INSERT 0 1 
postgres=# INSERT INTO test (name, address) VALUES ('john', 'rome'); 
ERROR: duplicate key value violates unique constraint "test_index" 
DETAIL: Key (name, address)=(john, rome) already exists. 

HTH

oluşturmalısınız Eğer boş değerler göz ardı benzersiz kayıtları zorlamak istiyorsanız SELECT DISTINCT

 
postgres=# SELECT * FROM test; 
name | address | college 
------+---------+--------- 
john | rome | 
john | rome | 
max | tokyo | 
(3 rows) 

postgres=# SELECT DISTINCT * FROM test; 
name | address | college 
------+---------+--------- 
john | rome | 
max | tokyo | 
(2 rows) 

kullanmak sorgu sonucu benzersiz kayıtları gerekiyorsa

İlgili konular