안녕하세요.
게시글 리스트 조회 시 댓글 개수를 가져오는것 까지는 해결했는데 여기에 첨부파일이 있으면 그 중 가장 먼저 업로드 된 파일도 하나 같이 조회를 할려고 합니다.
테이블은 다음과 같이 설계가 되어 있습니다.
<게시판 테이블>
게시글번호 | 제목 | 내용 | 글쓴이 | 작성일 |
1 | 블로그1 | 내용입니다1 | 관리자 | 2019-01-01 |
2 | 블로그2 | 내용입니다2 | 관리자 | 2019-01-02 |
3 | 블로그3 | 내용입니다3 | 관리자 | 2019-01-03 |
4 | 블로그4 | 내용입니다4 | 관리자 | 2019-01-04 |
<댓글 테이블>
댓글번호 | 게시글번호 | 내용 | 작성자 |
1 | 2 | 짱구댓글입니다 | 짱구 |
2 | 2 | 철수댓글입니다 | 철수 |
3 | 3 | 훈이댓글입니다 | 훈이 |
4 | 4 | 흰둥이댓글입니다 | 흰둥이 |
<첨부파일 테이블>
파일번호 | 게시글번호 | 파일이름 | 파일경로 | 파일사이즈 |
1 | 2 | /file.jpg | /2019/01/02 | 100 |
2 | 2 | /file2.png | /2019/01/02 | 200 |
3 | 3 | /doc.txt | /2019/01/03 | 150 |
위와 같이 데이터가 들어가 있다고 하면 아래와 같이 출력이 되길 원합니다.
<출력결과>
게시글번호 | 제목 | 글쓴이 | 작성일 | 댓글개수 | 파일이름 | 파일경로 |
1 | 블로그1 | 관리자 | 2019-01-01 | 0 | null | null |
2 | 블로그2 | 관리자 | 2019-01-02 | 2 | /file.jpg | /2019/01/02 |
3 | 블로그3 | 관리자 | 2019-01-03 | 1 | /doc.txt | /2019/01/03 |
4 | 블로그4 | 관리자 | 2019-01-04 | 1 | null | null |
게시글 리스트와 댓글개수는
select a.게시글번호, a.제목, a.글쓴이, a.작성일, count(b.댓글번호)
from 게시판 a left join 댓글 b on a.게시글번호 = b.게시글번호
group by a.게시글번호
로 구했는데 첨부파일까지 조회할려고 하니 잘 안되네요..
첨부파일이 여러개가 있다면 그 중 파일번호가 가장 작은걸 하나 불러올려고 합니다(제일 먼저 업로드된 순)
감사합니다.
1:m:n 조인을 한번에 하면 건수가 m*n 만큼 뻥튀기 됩니다.
1:m 조인 후 그룹바이 한뒤 다시 1:n 조인을 단계별로 하는 방법이 있습니다.
다만 이렇게 조인하는 방식은 페이징 처리를 염두에 두지 않은 방식인 듯 합니다.
1. 페이징 처리 전에 모든 정보를 다 가져오는 것은 비효율입니다.
- 게시글만 페이징 처리 후에 한 페이지에 대해서만 조인을 하는 것이 좋습니다.
2. 그룹바이 구문도 지금 mySQL 에서만 허용되는 비표준 구문입니다.
- mySQL 의 이 비표준 Group By 에 익숙해 있다가, 다른 DB 사용하시게 되면 적응 못할 수 있습니다.
- 표준 구문 사용 권장합니다.
3. 추가 사항
- 조인 대신 스칼라 서브쿼리를 이용할 수도 있습니다.
- 댓글과 첨부 테이블에는 반드시 "게시글번호" 인덱스가 있어야 합니다.
-- 1. Group By 표준 구문 권장, 페이징 후 조인 SELECT a.게시글번호 , a.제목 , a.글쓴이 , a.작성일 , a.댓글개수 , c.파일이름 , c.파일경로 FROM (SELECT a.게시글번호 , a.제목 , a.글쓴이 , a.작성일 , COUNT(b.댓글번호) 댓글개수 FROM (-- 우선 페이징 처리 -- SELECT 게시글번호, 제목, 글쓴이, 작성일 FROM 게시판 ORDER BY 게시글번호 DESC LIMIT 0, 10 ) a LEFT JOIN 댓글 b ON a.게시글번호 = b.게시글번호 GROUP BY a.게시글번호 -- 여기까지만 사용하면 비표준 , a.제목, a.글쓴이, a.작성일 -- 여기서부터 추가해야 표준 ) a LEFT JOIN 첨부파일 c ON a.게시글번호 = c.게시글번호 AND NOT EXISTS (-- Exists 구문을 활용하여 1건만 가져오기 SELECT 1 FROM 첨부파일 d WHERE d.게시글번호 = c.게시글번호 AND d.파일번호 < c.파일번호 ) ORDER BY 게시글번호 DESC ; -- 2. 스칼라 서브쿼리 사용 예 SELECT a.게시글번호 , a.제목 , a.글쓴이 , a.작성일 , (SELECT COUNT(b.댓글번호) FROM 댓글 b WHERE b.게시글번호 = a.게시글번호) 댓글개수 , c.파일이름 , c.파일경로 FROM (-- 1. 우선 페이징 처리 -- SELECT 게시글번호, 제목, 글쓴이, 작성일 FROM 게시판 ORDER BY 게시글번호 DESC LIMIT 0, 10 ) a LEFT JOIN 첨부파일 c ON a.게시글번호 = c.게시글번호 AND NOT EXISTS (-- 3. Exists 구문을 활용하여 1건만 가져오기 SELECT 1 FROM 첨부파일 d WHERE d.게시글번호 = c.게시글번호 AND d.파일번호 < c.파일번호 ) ORDER BY 게시글번호 DESC ;