JSON_ARRAYAGG는 원하는 항목을 JSON ARRAY로 추출한다.
JSON_OBJECT는 원하는 항목을 JSON OBJECT로 추출한다.
내가 구현하고자 했던 로직은 카테고리에 들어갔을 때 보여지는 리스트에 대한 데이터를 GET 요청이 들어오면 깔끔하게 정리해서 보내주는 것이였다.
Frontend 팀원 요청에 따라 maincategory에 name은 하나의 key값과 value값으로 subcategory와 products는 각각의 key 값 안에 배열에 객체 형태로 데이터를 담아서 보내주기로 하였다.
JSON_ARRAYAGG 안에 JSON_OBJECT를 담아 JSON_OBJECT 안에 key값과 value값을 넣는 방식으로 진행하였는데, 그 과정은 수월했다.
그러나,
subcategoryname과 products 2개를 각각의 key값에 담게 하기 위해
JSON_ARRAY를 각각 작성하였는데, 무슨 이유 때문인지 같은 값이 중복해서 여러번 출력되는 상황이 발생했다.
해결하기 위해 했던 조치
SELECT 절에 sub query를 사용해서 각각 하나의 값만 출력될 수 있게 함
최종 코드!
const getProductMainCategories = async (mainCategoryName) => {
const productsMainCategories = await appDataSource.query(`
SELECT
mc.name AS mainCategoryName,
(SELECT
JSON_ARRAYAGG(
JSON_OBJECT('name', sc.name)
)
FROM sub_categories AS sc
JOIN main_categories AS mc ON sc.main_category_id = mc.id
WHERE mc.name = '${mainCategoryName}'
) AS subCategories,
JSON_ARRAYAGG(
JSON_OBJECT(
'locationGroupName', lg.name,
'thumbnailImageUrl', p.thumbnail_image_url,
'name', p.name,
'price', p.price,
'discountRate', p.discount_rate
)
) AS products
FROM products AS p
JOIN sub_categories AS sc ON p.sub_category_id = sc.id
JOIN main_categories AS mc ON sc.main_category_id = mc.id
JOIN location AS l ON p.location_id = l.id
JOIN location_groups AS lg ON l.location_group_id = lg.id
WHERE mc.name = '${mainCategoryName}'
LIMIT 12 OFFSET 0
`);
return productsMainCategories;
}