İkinci tabloda eksik satırları almak için iki tabloya KATILMA


21

Basit bir oylama sisteminde

CREATE TABLE elections (
election_id int(11) NOT NULL AUTO_INCREMENT,
title varchar(255),

CREATE TABLE votes (
election_id int(11),
user_id int(11),
FOREIGN KEYs

bir kullanıcının oy verdiği seçimlerin listesini almak için aşağıdaki JOIN kullanılır

SELECT * FROM elections
JOIN votes USING(election_id)
WHERE votes.user_id='x'

ancak bir kullanıcının oy kullanmadığı seçim listesini nasıl alabilirim?

Yanıtlar:


21

İstediğiniz listenin karşısına geçmek için mevcut sorgunuzu kullanın. Bu liste daha sonra istenen listeyi almak için NOT IN üzerinden kontrol edilebilir.

SELECT * FROM elections WHERE election_id NOT IN (
    SELECT elections.election_id from elections
    JOIN votes USING(election_id)
    WHERE votes.user_id='x'
)

17

Dış birleştirme kullanın:

select e.election_id, e.title, v.user_id
from Elections e
 LEFT OUTER JOIN votes v ON v.election_id = e.election_id and v.user_id = @userid

Belirli bir seçim için herhangi bir oy kullanılmamışsa UserId boş olur, aksi takdirde bu

Yalnızca herhangi bir oy kullanmayan seçimleri listelemek istiyorsanız, bunu şöyle yapabilirsiniz:

select *
from elections e
where election_id NOT IN 
 (select election_id
  from votes
  where user_id = @userid
 )

5

İ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 EXISTSyü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 INYü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)
);   

-3
SELECT * 
FROM elections 
WHERE election_id NOT IN (
    SELECT DISTINCT(election_id) from votes
);

4
Kabul edilen cevap, belirli bir seçmenin oy kullanmadığı seçimleri çektiği için, bu OP'nin sorusuna gerçekten cevap vermiyor. Ve elbette, hiç kimsenin oy kullanamadığı seçimler almak, diğer cevaplardan birinin küçük bir ince ayarı. Bu etkiye yapılan bir yorum, bunu biraz daha iyi bir cevap gibi gösterebilir. Yine de, resimden, bir maymun için oldukça iyi! :-)
RDFozz
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.