Cách THAM GIA hai bảng để nhận các hàng bị thiếu trong bảng thứ hai


21

Trong một hệ thống bỏ phiếu đơn giản như

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

để có được danh sách các cuộc bầu cử mà người dùng đã bỏ phiếu, THAM GIA sau đây được sử dụng

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

nhưng làm thế nào để có được danh sách bầu cử mà người dùng KHÔNG bình chọn?

Câu trả lời:


21

Sử dụng truy vấn hiện tại của bạn để có được đối diện của danh sách bạn muốn. Danh sách đó sau đó có thể được kiểm tra thông qua KHÔNG VÀO để có được danh sách mong muốn.

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

Sử dụng nối ngoài:

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

UserId sẽ trống nếu không có phiếu bầu nào cho một cuộc bầu cử cụ thể, nếu không nó sẽ xuất hiện

Nếu bạn chỉ muốn liệt kê các cuộc bầu cử trong đó không có bất kỳ phiếu bầu nào, bạn có thể làm như thế này:

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

5

Có rất nhiều cách để đạt được những gì bạn đang yêu cầu. Có lẽ cách đơn giản nhất là sử dụng cách tiếp cận hoàn toàn theo định hướng:

select election_id from elections
minus -- except is used instead of minus by some vendors
select election_id from votes where user_id = ?

Từ bộ bầu cử, chúng tôi loại bỏ những nơi mà người dùng đã bỏ phiếu. Kết quả có thể được tham gia với các cuộc bầu cử để có được danh hiệu của các cuộc bầu cử. Mặc dù bạn chưa gắn thẻ câu hỏi của mình, vẫn có lý do để tin rằng bạn đang sử dụng MySQL và MINUS hoặc EXCEPT không được hỗ trợ ở đó.

Một biến thể khác là sử dụng NOT EXISTSvị ngữ:

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 = ?
);

Tức là cuộc bầu cử nơi nó không tồn tại một cuộc bỏ phiếu từ người dùng. CácNOT IN ngữ có thể được sử dụng theo cách tương tự. Vì có thể có null liên quan, điều đáng chú ý là ngữ nghĩa khác nhau giữa IN và EXISTS.

Cuối cùng, bạn có thể sử dụng một tham gia bên ngoài

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;

Nếu không có hàng nào khớp với vị từ ON, thì tất cả các cột từ phiếu bầu sẽ được thay thế bằng null trong kết quả. Do đó, chúng tôi có thể kiểm tra xem có bất kỳ cột nào từ phiếu bầu là null trong mệnh đề WHERE không. Vì cả hai cột trong phiếu bầu có thể là null nên bạn cần cẩn thận.

Tốt nhất, bạn nên sửa các bảng của mình để không phải đối phó với các vấn đề gây ra bởi null:

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
Vì câu trả lời được chấp nhận đã kéo theo các cuộc bầu cử mà một cử tri cụ thể không bỏ phiếu, điều này không thực sự trả lời câu hỏi của OP. Và, tất nhiên, đó chỉ là một điều chỉnh nhỏ của một trong những câu trả lời khác, để có được các cuộc bầu cử mà không ai bỏ phiếu. Một nhận xét cho hiệu ứng đó có thể làm cho điều này có vẻ như một câu trả lời tốt hơn một chút. Tuy nhiên, từ hình ảnh, khá tốt cho một con khỉ! :-)
RDFozz
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.