2010-03-03 17 views
5

tiêu đề có thể là một chút bối rối, hãy để tôi giải thích,;) Tôi có 3 bảng:Làm cách nào để liệt kê các mục không tồn tại?

[names] 
n_id;name 
1;Jeff 
2;Adam 

[books] 
b_id;title 
1;Book1 
2;Book2 

[read] 
n_id;b_id 

Bảng [đọc] là một bảng với những cuốn sách đọc. nếu Adam đọc "Book1" mục trong [đọc] trông như thế này:

2;1 

cho đến nay, như vậy tốt. Bây giờ, có cách nào để biết sách nào đã được đọc bởi một người không? Chúng ta biết rằng chỉ Adam đọc một cuốn sách "Book1", do đó truy vấn nên ra một cái gì đó như thế này:

n_id;name;b_id;title 
1;Jeff;1;Book1 
1;Jeff;2;Book2 
2;Adam;2;Book2 

là nó có thể làm điều này trong 1 truy vấn hay tôi cần một số kịch bản?

Trả lời

2

Bạn có thể sử dụng một CROSS JOIN để có được tất cả các kết hợp có thể có của namesbooks và sau đó sử dụng một LEFT JOIN trên read với IS NULL để loại bỏ hàng tồn tại ở đó.

LEFT JOIN trả về NULL cho tất cả các cột được nối mà không có hàng nào tồn tại, vì vậy hãy kiểm tra xem r.n_id IS NULL có xóa các hàng đó khi thực sự tham gia tìm thấy các hàng trong read hay không.

SELECT n.n_id, n.name, b.b_id, b.title 
FROM names n 
CROSS JOIN books b 
LEFT JOIN read r ON (r.n_id = n.n_id AND r.b_id = b.b_id) 
WHERE r.n_id IS NULL 
1

Bạn cần tham gia chéo để tạo tất cả các cặp name so với book và sau đó tham gia với bảng read và kiểm tra nơi kết nối không thành công.

SELECT names.n_id, names.name, books.b_id, books.title 
FROM names 
CROSS JOIN books 
LEFT JOIN read 
ON names.n_id = read.n_id AND books.b_id = read.b_id 
WHERE read.n_id IS NULL 
1

Bạn sẽ làm một Descartes tham gia giữa tên và sách để có được tất cả các tổ hợp tên/cuốn sách có thể, sau đó trừ đi những người mà đã được đọc:

SELECT n_id, b_id 
FROM names, books 
MINUS 
SELECT n_id, b_id 
FROM read 

Những người khác đã đề nghị thực hiện một chéo tham gia và một tham gia trái, mà cũng sẽ làm việc hoàn toàn tốt. Có thể muốn thử cả hai để xem cái nào nhanh hơn trong kịch bản thế giới thực - tôi nghi ngờ những người khác tham gia bên trái được đề xuất sẽ nhanh hơn, nhưng không thực sự chắc chắn.

0

Câu hỏi của bạn là: "Có cách nào để biết được sách werent đọc bởi một người?" Nhưng kết quả truy vấn mẫu của bạn cho thấy câu trả lời cho câu hỏi, "Có cách nào để biết sách nào không được mọi người đọc hay không?"

Nếu bạn đang thực sự tìm kiếm chỉ để chạy các truy vấn cho một người cụ thể, một cái gì đó như thế này nên làm việc:

SELECT b_id, title 
FROM books --You said you're just looking for books 
WHERE b_id NOT IN 
    (SELECT b_id 
    FROM read 
    WHERE n_id = @names_id) --pass in the names_id as a parameter 
Các vấn đề liên quan