문제
Table_A - Table_B 가 OneToMany 관계를 가진 상태였고, Table_A 의 각 row별로 Table_B의 데이터가 필요한 상황이었다.
Table_A의 각 row별로 Table_B의 가장최신 데이터를 3개씩 가져오는것이 목표였다.
즉 대충 구조를 그리면 다음과 같은 상황이었다.
table_a_row1
table_b_data1
table_b_data2
table_b_data3
table_a_row2
table_b_data4
table_b_data5
table_b_data6
table_a_row3
table_b_data7
table_b_data8
table_b_data9
table_a_row4
table_b_data10
table_b_data11
table_b_data12
LeftJoin 으로 해결을 보려했지만 SubQuery를 통한 Limit 동작 방식이 내가 생각하는 방식이 아니었기 때문에 제대로 된 결과를 얻기 힘들었다.
그렇게 계속 검색을 하던중에 LATERAL JOIN을 알게되었다.
LATERAL JOIN
stackoverflow에 올려놓은 답변글에 누군가 사용한 LATERAL 구문을 보고 검색을 시작했는데 생각보다 자료가 없었다. 아무래도 추가된지 오래되지않아서 관련 자료가 없는듯 했다.(https://stackoverflow.com/questions/50563043/how-can-you-simulate-a-lateral-join-in-mysql-v8-to-execute-a-subquery-or-join-fo)
join문에서 사용방법은 다음과 같았다.
SELECT *
FROM TABLE_A AS a
LEFT JOIN LATERAL (
SELECT *
FROM TABLE_B
WHERE TABLE_B.tableAId = a.id
ORDER BY TABLE_B.createdAt DESC
LIMIT 3
) AS b
ON b.tableAId = a.id
ORDER BY a.createdAt DESC
LIMIT 0, 5
TABLE_A를 생성일 기준으로 정렬 및 pagination 하되 각 row별로 불러오는 TABLE_B도 정렬 및 Limit를 걸어주는 구문이다.
여태까지 DB다루면서 join문 몇개만 알고 그 안에서 해결을 보려하니 쿼리가 복잡해졌는데 아무래도 공부가 부족했던거같다는 생각을 이번에 검색하면서 느끼게 되었다.
조만간 Mysql 최신 문법기준으로 정리된 책 한번 읽어봐야겠다.