İstediğinizi başarmanın birçok yolu var. Belki de en basit yol tamamen ayarlanmış bir yaklaşım kullanmaktır:
select election_id from elections
minus -- except is used instead of minus by some vendors
select election_id from votes where user_id = ?
Seçim kümesinden, kullanıcının oy kullandığı seçimleri kaldırıyoruz. Sonuç, seçimlerin başlığını almak için seçimlerle birleştirilebilir. Sorunuzu etiketlememiş olsanız bile, MySQL kullandığınıza inanmanız için bir neden var ve MINUS veya EXCEPT burada desteklenmiyor.
Başka bir varyant NOT EXISTS
yüklemi kullanmaktır :
select election_id, title
from elections e
where not exists (
select 1
from votes v
where e.election_id = v.election_id
and v.user_id = ?
);
Yani seçimin kullanıcı tarafından yapılmadığı bir seçim. NOT IN
Yüklem benzer bir şekilde kullanılabilir. İlgili boş değerler olabileceğinden, anlambilimin IN ve EXISTS arasında farklı olduğunu belirtmek gerekir.
Son olarak, dış birleştirme kullanabilirsiniz
select election_id, title
from elections e
left join votes v
on e.election_id = v.election_id
and v.user_id = ?
where v.user_id is null;
ON yüklemiyle eşleşen satır yoksa, oydaki tüm sütunlar sonuçta null ile değiştirilir. Bu nedenle, WHERE yan tümcesinde oylardan herhangi bir sütunun boş olup olmadığını kontrol edebiliriz. Oylardaki her iki sütun da boş olabileceğinden dikkatli olmanız gerekir.
İdeal olarak, null'ların neden olduğu gotcha'larla uğraşmak zorunda kalmamak için tablolarınızı düzeltmelisiniz:
CREATE TABLE elections
( election_id int NOT NULL AUTO_INCREMENT PRIMARY KEY
, title varchar(255) not null );
CREATE TABLE votes
( election_id int not null
, user_id int not null
, constraint pk_votes primary key (election_id, user_id)
, constraint fk_elections foreign key (election_id)
references elections (election_id)
);