2010-04-06 6 views
0

태그 필터링 기능을 사용하여 앱을 만드는 메모를 작성 중이지만 태그로 메모를 가져 오는 동안 문제가 발생했습니다. 태그 필터는 IN이 아닌 AND를 사용해야합니다. 왜냐하면 내가 찾고있는 것을 좁히는 데 도움이되기 때문입니다.MySQL LEFT JOIN 문제 (WHERE 문 세 개 포함)

내 테이블은 다음과 같이 구성됩니다

+ notes   note_id | note_title | note_uid 

+ tags   tag_id | tag_title 

+ notes_tags  nt_id | nt_note_id | nt_tag_id 

notes_tags 테이블은 모든 노트 '태그를 추적합니다.

그래서 여기에 예를 들어 왼쪽 난 단지 단 1 개 태그로 노트를 얻기 위해 현재 사용하고 조인, 태그에 대한 정보를 반환 걱정 아닙니다. 왼쪽부터 notes_tags

SELECT *는 참고 사항 가입 note_id = nt_note_id WHERE note_uid IN (1) 및 nt_tag_id이 쿼리가 완벽한 실행 10

, 그것은 그 단일 태그으로 모든 노트를 잡고 = . LEFT 메모를 가입 notes_tags FROM note_id = nt_note_id WHERE note_uid IN (1) 및 nt_tag_id = 10 및 nt_tag_id = 11 ON

SELECT * 그러나,이 같은 쿼리를 사용하여 내 노트 "를 정확히 파악"문제가 있어요

구문에 어떤 오류가 있습니까?

+0

태그 10과 11 모두에있는 메모를 얻으려고합니까? 그냥 AND로 할 수는 없지만 어제부터 이와 비슷한 질문을보세요 : http://stackoverflow.com/questions/2581067/mysql-experts-need-help-with-intersect/2581145#2581145 –

답변

2

nt_tag_ids 10과 nt_tag_ids가 11 인 관련 notes_tags 레코드가있는 노트를 식별하려는 경우 외부 조인은 DBMS를 필요 이상으로 어렵게 만듭니다.

이 가장 확실한 해결책 보인다

SELECT * FROM notes n 
WHERE EXISTS (SELECT 1 FROM notes_tags nt 
    WHERE n.note_id=nt.nt_note_id 
    AND nt.nt_tag_id=10) 
AND EXISTS (SELECT 1 FROM notes_tags nt2 
    WHERE n.note_id=nt2.nt_note_id 
    AND nt2.nt_tag_id=11); 

다른 방법은 다음과 같습니다이이 notes_tags 테이블에 nt_note_id 및 nt_tag_id에 고유 제한 조건들이는 것을 전제로

SELECT n.*, COUNT(*) 
FROM notes n, 
notes_tags nt 
WHERE n.note_id-nt.nt_note_id 
AND nt.nt_tag_id IN (10,11) 
GROUP BY .... /* need to add these */ 
HAVING COUNT(*)=2; 

참고.

하지만 위의 두 가지 모두 메모 테이블의 데이터 만 반환합니다. 당신이 MN 분해 테이블에서 해당 행을 추출해야하는 경우 :

SELECT * 
FROM notes n, 
notes_tags nt, 
notes_tags nt2 
WHERE n.note_id=nt.nt_note_id 
AND n.note_id=nt2.note_id 
AND nt.nt_note_id=nt2.nt_note_id /* can help the optimizer come up with a faster query */ 
AND nt.nt_tag_id=10 
AND nt2.nt_tag_id=11 

당신은 쉽게 응답 조금을 분석하기 위해 출력 열에 별칭을 추가 할 수 있습니다.당신이 사용하는 'AND'하는

+0

고마워! 이것은 완벽하게 작동합니다. – hatfieldajoshua

2

nt_tag_id = 10 AND nt_tag_id = 11이 항상 false

사용 nt_tag_id in (10,11)를 반환하는 대신

둘 다 태그를 필요로하는 경우 두 번

+0

using IN (10, 11)은 10 * 또는 * 11에있는 노트를 원하지만 10 * 및 * 11에있는 노트를 원하는 경우에는 사용할 수 없습니다. –

+0

나는 하나의 필드가 10과 11을 똑같이 동일시 할 수 없다고 추측했다. simultaniously – vittore

2

tag_id 모두에만 노트를 반환합니다 태그 테이블에 합류와 함께 아래에 답이있다 10 및 11입니다.

SELECT notes.* 
FROM notes 
INNER JOIN notes_tags a ON notes.note_id = a.nt_note_id 
         AND a.nt_tag_id = 10 
INNER JOIN notes_tags b ON notes.note_id = b.nt_note_id 
         AND b.nt_tag_id = 11 
0

대신이 같은 조항은 어디에서 그 사용 'OR'의 : 더 nt_tag_id를 추가하려는 경우

SELECT * FROM notes_tags LEFT JOIN notes ON note_id = nt_note_id WHERE note_uid IN (1) AND (nt_tag_id = 10 OR nt_tag_id = 11) 

당신은이 같은도에서 사용 할 수 있습니다.

SELECT * FROM notes_tags LEFT JOIN notes ON note_id = nt_note_id WHERE note_uid IN (1) AND nt_tag_id IN (10, 11)