하나의 글에 연관된 여러 개의 이미지 출력하고 싶을 때가 있다. 인스타그램을 떠올려보면 쉽게 이해가 갈 것이다.
우리가 원하는 데이터의 형태는 게시물(post) 하나에 여러 개의 이미지가 묶여서 하나의 행으로 구성되는 것이다(이때, 이미지는 blob형태가 아닌 varchar로 주소의 형태로 저장된다고 가정한다). 말로 하면 살짝 이상한데, 객체 형태로 표현하자면 다음과 같다.
{ id: 1, content:"글1", paths: [...] }
어떻게 쿼리를 작성할 수 있을까? 다음과 같은 테이블이 있다고 가정하자.
posts 테이블
ID | CONTENT |
1 | 글1 |
2 | 글2 |
3 | 글3 |
images 테이블
ID | POST_ID(FK) | PATH |
1 | 1 | /path1 |
2 | 2 | /path2 |
3 | 2 | /path3 |
4 | 2 | /path4 |
5 | 3 | /path5 |
6 | 3 | /path6 |
SELECT와 JOIN으로 전체 데이터를 가져온 후 호스트 프로그램 내에서 처리를 해주거나 SELECT를 두 번해서 post와 image 데이터를 각각 가져온 후 column을 합치는 방법도 있다. 하지만, MySQL에서 제공하는 함수를 이용하면 간단하게 처리할 수 있다.
그 함수는 바로 GROUP_CONCAT이다! GROUP_CONCAT을 사용할 때 주의해야 할 점은 집계 함수이기 때문에 항상 GROUP BY와 함께 써주어야 한다는 것이다.
GROUP_CONCAT을 이용하여 작성한 쿼리는 다음과 같다.
SELECT *
FROM posts AS p
INNER JOIN (
SELECT
post_id,
GROUP_CONCAT(path) AS paths
FROM images
GROUP BY post_id) AS i
ON (p.id = i.post_id)
images 테이블에서 post_id 별로 그룹을 나눈 후, 그룹에 해당하는 path들을 하나로 합친다(concat). 그 후 posts 테이블과 JOIN을 통해 데이터를 출력한다. 이렇게 해서 하나의 글과 그와 관련된 여러 이미지들을 묶을 수 있다. 최종적으로 split 함수를 이용해 적절하게 나눠서 이미지 경로를 추출하면 된다.
별 거 아닌 쿼리지만, 복잡하게 생각하면 한없이 복잡하게 짤 수도 있다(나처럼..). 다른 사람은 나같은 삽질을 하지 않길 바라며 포스팅을 마친다.
'CS > SQL' 카테고리의 다른 글
[SQL] 실행 계획(Execution Plan) 보는 방법 (0) | 2023.08.11 |
---|---|
[SQLD] SQLD 합격 후기 및 공부 방법 (6) | 2021.04.18 |
[MySQL] Connection Pool을 사용하는 이유 (0) | 2021.04.16 |
[SQLD] Join 연산 정리 (0) | 2021.03.18 |
[MySQL] MySQL에서 CSV파일 Import하기 (5) | 2021.02.10 |