2012-08-13 3 views
1

태그 시스템을 만들기를 원하는 클라이언트가 있습니다. items, tagsitem_tag_assoc 세 개의 표가 있습니다. 마지막 표는 item_ids와 tag_ids를 연결하는 역할 만합니다. 여기에 내가 가지고있는 문제는 다음과 같습니다.다중 포함 및 제외를위한 MySQL 콤플렉스 조인

사용자가 포함 된 태그 [1, 2, 3] 및 제외 태그 [4, 5, 6]를 요청하면 결과는 EVERY 태그가있는 모든 항목이어야합니다 [ 1, 2, 3] (단 하나가 아님)이고 NO 태그가 [4, 5, 6]에 있습니다. 이 작업을 수행하는 방법은 무엇입니까?

SELECT i.item_id, i.item_title FROM items AS i INNER JOIN tag_item_assoc AS tia1 ON (tia1.item_id = i.item_id AND tia1.tag_id = 1)

을 ... 그리고 포함 할 같은 내부에 단지 체인은 많은 태그 패턴을 조인

나는 내부는 태그 포함 조인 알아낼 수있을만큼 연구. 약간 부피가 클 수 있지만 사용자가 이동하기 전에 4 개 또는 5 개의 태그를 선택하지 않을 것이므로 그렇게 할 것입니다.

것은 정말 내가 하나 개의 쿼리로 모든 것을 같은 방법을 제외하고, 포장 수 있다고 기대했다 :

INNER JOIN tag_item_assoc AS tia2 ON (tia2.item_id = i.item_id AND tia2.tag_id!= 2)

하지만 그 일을하지 않을했다 매우 빠르게 명백하게되었다. 나는 포함하는 동안 LEFT OUTER JOIN s가 나를 제외시킬 수 있다고 말했던 몇 가지 기사를 읽었지 만, 주로 떠돌아 다니는 것 때문에 그들을 알아 내지 못했습니다. WHERE 조항. LEFT OUTER JOININNER JOIN s의 순열 중 하나를 시도했는데 오류가 발생하거나 매우 혼란 스러웠습니다.

모든 것 - 여기 누가 내가 이것을 성취 할 수 있는지 알고 있습니까? 유용한 코드 예제가없는 것에 대해 사과드립니다. INNER JOIN이 장애가되면 처음부터 시작하는 것이 좋습니다. 동시에 여러 연관 결합 및 제외를 수행하는 방법이 필요합니다. 도움과 전문 지식에 미리 감사드립니다!

+0

은 태그 IN (1, 2, 3) –

+0

처럼 간단 할 수 있습니다. IN (1, 2, 3)은 태그 [1], [1, 3] 등이있는 항목과 일치합니다. 집합 [1, 2, 3]에있는 모든 태그가있는 항목 만 찾습니다. 답변 해 주셔서 감사합니다. – CodeMoose

+0

샘플 데이터와 샘플 출력을 제공 할 수 있다면 도움이 될 것입니다. – Omesh

답변

0

답을 찾을. 대신과 같이 INNER JOIN의 추가의 : INNER JOIN tag_item_assoc AS tia2 ON (tia2.item_id = i.item_id AND tia2.tag_id!= 2)

내가 하나의 내부와 하위 쿼리를 추가 가입 :

WHERE i.item_id NOT IN (SELECT i.item_id FROM items AS s INNER JOIN tag_item_assoc AS tia1 ON (tia1.item_id = i.item_id AND tia1.tag_id IN (4, 5, 6)))

하위 쿼리가 모든 item의 집합을 만듭니다 [4, 5, 6]에있는 태그가 있고 WHERE i.iten_id NOT IN은 해당 세트와 일치하는 레코드를 제거합니다.

모두에게 감사드립니다. 바라기를 이것은 길 아래 사람을 도울 것입니다.

0

당신은 태그의 수에 레코드의 인스턴스의 수와 일치해야합니다

SELECT a.item_id -- , add other columns here 
FROM items a 
      INNER JOIN item_tag_assoc b 
      ON a.item_id = b.item_id 
WHERE b.tag_id IN (1, 2, 3) AND 
     b.tag_id NOT IN (4, 5, 6) 
GROUP BY a.item_id 
HAVING COUNT(a.item_id) = 3 
+0

답변을 주셔서 감사합니다, 그게 내가 생각해 낸 해결책보다 훨씬 더 우아합니다. 유사한 방법으로 태그를 제외 할 수있는 방법이 있습니까? – CodeMoose

+0

@CodeMoose가 작동합니까? –

+0

정확하게는 - (1, 2, 3)은 잘 작동하지만 (4, 5, 6) 부분은 나에게 잘못되었습니다. 제외하려고하는 세트를 포함하지 않습니까? – CodeMoose

0
SELECT a.* 
FROM items a 
    INNER JOIN item_tag_assoc b 
     ON a.item_id = b.item_id 
    INNER JOIN tags c 
     ON a.tag_id = c.tag_id 
WHERE c.tag_id IN(1) AND 
     c.tag_id IN(2) AND 
     c.tag_id IN(3) AND 
     c.tag_id NOT IN (4) AND 
     c.tag_id NOT IN (5) AND 
     c.tag_id NOT IN (6) ; 
+0

이 쿼리를 시도한 적이 있습니까? – Imdad

+0

내가 한 것 - 아직 내가 뭘 찾고 있는게 아니야. 그래도 고마워! – CodeMoose