2010-03-03 5 views
5

제목이 조금 혼란 스러울 수도, 내가, 설명하자) 내가 3 개 테이블이 :존재하지 않는 항목을 나열하는 방법은 무엇입니까?

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

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

[read] 
n_id;b_id 

표는 [ 읽기] 읽기 책과 함께 테이블입니다. 아담은 "Book1을"는 항목에 읽는 경우 [읽기] 다음과 같습니다

2;1 

를 지금까지 너무 좋아. 이제는 사람이 읽을 수없는 책을 알 수있는 방법이 있습니까? 우리는 아담이 책 "Book1을"를 읽어 것을 알고, 그래서 쿼리해야 다음과 같은 결과물을 출력 할 것

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

은 1 개 쿼리에서이 작업을 수행하거나 좀 스크립트를 필요로 할 수 있습니까?

답변

2

당신은 namesbooks의 모든 가능한 조합을 얻을 수있는 CROSS JOIN를 사용하여 다음 존재 행을 제거하는 IS NULLreadLEFT JOIN를 사용합니다.

LEFT JOIN은 행이없는 모든 조인 된 열에 대해 NULL을 리턴하므로 r.n_id IS NULL이 조인이 실제로 행을 찾은 행을 read에 제거했는지 확인하십시오.

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

namebook의 모든 쌍을 생성하려면 크로스 조인을 수행 한 다음 read 테이블과 조인하고 조인이 실패한 곳을 확인하십시오. 당신은 직교 할 것

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

다음, 모든 가능한 이름/도서 조합을 얻기 위해 이름과 책 사이의 조인을 뺀 읽은 것들 :

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

기타 크로스에 가입하고 제안 및 왼쪽 조인도 완벽하게 작동합니다. 실제 시나리오에서 어떤 것이 더 빠르는지 알아보기 위해 노력하고 싶을 수도 있습니다. 제안 된 다른 사람들과의 조인이 더 빠르지 만 확실하지는 않다고 생각합니다.

0

귀하의 질문이었다 " 사람이 읽기를 werent 책이 어떤 책인지 알 수있는 방법이 있나요?" 그러나 샘플 쿼리 결과는 "모든 사람들이 읽지 않은 책을 알 수있는 방법이 있습니까?"라는 질문에 대한 대답을 보여줍니다. 당신이 정말로 특정 사람에 대한 쿼리를 실행 단지 찾고 있다면

,이 같은 작업을해야합니다 :

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 
관련 문제