안녕하세요, 팀프로젝트를 하던 와중 제가 검색 관련 담당이라 골치를 썩이는게 있어서
선배 개발자분들께 의견을 듣고자 글을 작성합니다.
현재 DB의 구조는 이러한 형식을 가지고 있습니다.
그리고 중간 테이블의 정보는 이러한 형식으로 되어있습니다.
제가 지금 하고 싶은 것은 검색기능의 일부인데
boardSide의 tagName이 여러개 들어간 것에 대한 조회를 하고 싶습니다. (다나와의 태그를 눌러서 검색하는 것과 비슷합니다.)
또한 제가 board.boardSide, boardSide.tagName = "닭고기"의 형식을 쏘면
board에 닭고기가 조인되어있던 board의 정보(위 사진에서는 저렇게 5줄)이 나올 것이라고 생각을 했는데
닭고기가 포함되어있는 Board + BoardSide테이블 한줄만 나오는 것을 발견하였습니다(...)
SELECT b.*, bt.*, bs.* FROM board b LEFT JOIN board_side bs ON bs.boardId = b.boardId LEFT JOIN board_tag bt ON bt.boardTagId = bs.boardTagId HAVING bs.TagName = "회사동료" ANDHAVING bs TagName = "관악구"
만약 위와 같이 검색을 할 경우 회사동료와 관악구라는 것이 조인되어있는 상태의
board를 확인해보고 싶습니다.
////
더불어서 bs.TagName에서 관악구를 검색할 경우
아래의 SQL문과 결과가 똑같도록
관악구가 포함되어있는
board를 불러오되, 아래에 형성되어있는
boardSide의 관악구, 닭고기, 회사동료, 서울특별시, 피자 총 5개의 테이블도 전부 가져올 수 있는 방법은 없을까요?
SELECT b.*, bt.* , bs.* FROM board b LEFT JOIN board_side bs ON bs.boardId =b.boardId LEFT JOIN board_tag bt ON bt.boardTagId = bs.boardTagId WHERE b.boardId = "1";
어떤식으로 풀어나가야할지 도움을 받아보고자 글을 작성해봅니다.
1. 습관적 아우터 조인 사용 지양
- inner join 을 기본으로 사용한다 생각하고
- 꼭 필요할 때만 아우터 조인 사용한다고 생각하여야 합니다.
- bs.TagName 에 대한 조건을 주는데 아우터 조인은 잘못된 사용입니다.
2. SELECT * 사용 지양
- 필요한 항목만 지정하여 나열해 주세요.
3, 비표준 구문 사용 지양
- 문자를 표시하는 따옴표는 홑따옴표가 표준입니다.
- Having 조건 주는 부분도 그룹바이 표준에 어긋납니다.
SELECT * FROM board b INNER JOIN board_side bs ON bs.boardId = b.boardId INNER JOIN board_tag bt ON bt.boardTagId = bs.boardTagId INNER JOIN (SELECT boardId FROM board_side WHERE TagName IN ('닭고기') GROUP BY boardId HAVING COUNT(*) = 1 -- 검색어 개수 ) a ON a.boardId = b.boardId ; SELECT * FROM board b INNER JOIN board_side bs ON bs.boardId = b.boardId INNER JOIN board_tag bt ON bt.boardTagId = bs.boardTagId INNER JOIN (SELECT boardId FROM board_side WHERE TagName IN ('회사동료', '관악구') GROUP BY boardId HAVING COUNT(*) = 2 -- 검색어 개수 ) a ON a.boardId = b.boardId ;