티스토리 뷰

발생일: 2010.02.10

문제:
업무 공유를 위해 팀원끼리 사용할 간단한 게시판을 하나 만들고 있다.

한 게시물에 여러 개의 태그를 달 수 있는 게시판이며, 태그는 < 게시물 1 : n 태그 > 형태로 구성되어 있다.
또한 gmail 의 목록처럼, 전체 목록을 뿌릴 때 엮여 있는 모든 태그를 보여준다.


업무 게시판

업무 게시판




좌측 메뉴에서 태그를 선택할 경우, 아래와 같이 해당 태그에 해당하는 게시물만 필터링하려고 한다.





그러다 매핑 테이블에서 and 조건으로 조회를 하려다가 난관에 봉착했다.
매핑 테이블에서 AND 조건을 추가하기가 쉽지 않다.

task 테이블과 tag 테이블이 존재하며 매핑 테이블은 아래와 같이 구성되어 있다.

[task_tag_map]
task_id
tag_id

데이터 샘플은 아래와 같다.
(task_id, tag_id)
(1, 2)
(1, 4)
(2, 1)
(2, 4)
(3, 1)
(3, 4)
(3, 5)

기존에는 아래와 같은 형태로 tag_id 를 받아와 조회했는데,
이 경우 OR 조건으로 선택한 태그를 포함한 모든 목록을 보여준다.

SELECT *
FROM task
WHERE
    task_id IN (
        SELECT task_id
        FROM task_tag_map
        WHERE tag_id IN (1, 4) -- 이 부분의 tag_id 를 패러미터로 가져와 넣는다
    )



이 경우, 위 데이터 샘플을 기준으로 조회하면 아래와 같은 결과가 나온다.

(task_id, tag_id)
(1, 4)
(2, 1)
(2, 4)
(3, 1)
(3, 4)

원하는 대로라면 2번과 3번 게시물만 조회되어야 하는데 말이다.

어떤 식으로 해야할까....


해결책:
한 게시물 당, 중복된 태그는 없기 때문에 count 를 조건에 추가했다.
1번과 4번 태그를 포함한 결과라면 결과가 2건 이상이어야 하기 때문이다.

아래와 같이 수정해서 문제를 해결했다.

SELECT *
FROM task
WHERE
    task_id IN (
        SELECT task_id
        FROM task_tag_map
        WHERE
            tag_id IN (1, 4) -- 이 부분의 tag_id 를 패러미터로 가져와 넣는다
        GROUP BY task_id
        HAVING COUNT(*) >= 2 -- 이 값은 tag_id 의 개수의 값으로, 유동적이다
    )



수정한 쿼리로 조회하면, 원하는 결과를 얻을 수 있다.

(task_id, tag_id)
(2, 1)
(2, 4)
(3, 1)
(3, 4)


반응형
댓글
공지사항