원래는 해당 강의 id를 받아 내가 북마크 했는지 안했는지만 따로 체크하는 api를 만들었는데, 전체 강의 get함수에서 내가 북마크 했는지 안했는지를 덧붙여 체크 하도록 변경해야했다.
처음 작성한 잘못된 코드 :
query
.leftJoin(Review, 'review', 'review.courseId = course.id')
.select([
'course.id',
'course.title',
'course.platform',
'course.price',
'course.categoryBig AS course_categoryBig',
'category.category AS course_category',
'course.siteUrl AS course_siteUrl',
`DATE_FORMAT(course.createdAt, '%Y-%m-%d') AS course_createdAt`,
'instructor.id',
'instructor.name',
'IFNULL(review.num_review,0) AS num_review',
'IFNULL(review.avg,0) AS course_avg',
]);
// 유저가 로그인 했을 시
if (user) {
const Liked = this.likesRepository
.createQueryBuilder()
.subQuery()
.select(['like.courseId AS courseId', 'like.userId AS userId'])
.from(Likes, 'like')
.groupBy('like.courseId') // -> 잘못된 부분
.getQuery();
query
.leftJoin(Liked, 'liked', 'liked.courseId = course.id')
.addSelect(`IF(liked.userId =:userId,'true','false') AS course_liked`)
.setParameter('userId', user.id);
}
return query;
처음엔 이렇게 Liekd라는 subquery를 만들어서 했다. 해당 course id와 같은 liked의 courseId와 해당 course의 id와 같은 것으로 Join해서 로그인 한 유저의 아이디가 liked의 userId와 같으면 true 아니면 false로 나오게 하였다.
하지만 Liked에서 courseId로 groupBy한 것이 문제였다.
courseId로 groupBy를 했을 시 해당 courseId에는 하나의 userId로만 겹쳐지게 된다. groupBy를 하면 안됐다! (생각을 하고 쿼리를 짜자. 제발..)
if (user) {
const Liked = this.likesRepository
.createQueryBuilder()
.subQuery()
.select(['like.courseId AS courseId', 'like.userId AS userId'])
.from(Likes, 'like')
.getQuery();
query
.leftJoin(
Liked,
'liked',
'liked.courseId = course.id AND liked.userId =:userId',
{ userId: user.id },
)
.addSelect(
`IF(liked.courseId,'true','false') AS course_liked`,
);
}
return query
그래서 이제 Liked에 groupBy를 없애고 subquery와 Join할 조건을 2개로 하여 Liked테이블에서 해당 courseId와 로그인 한 userId와 같은 것으로 Join하여 Join된 것이 있으면 true 없으면 false로 나오게 했다.
근데 다시 생각해보니까 굳이 subquery를 할 필요가 없었다.
SQL 문법으로 하나하나 적어보니 너무 간단한 것이었다.
내가 너무 복잡하게 생각했다. Likes라는 테이블이 있는데 왜 이렇게 까지 생각했을 까 싶다.
변경한 코드:
if (user) {
query
.leftJoin(
Likes, // Likes 테이블 (courseId, userId있음)
'liked',
'liked.courseId = course.id AND liked.userId =:userId',
{ userId: user.id },
)
.addSelect(`IF(liked.courseId,'true','false') AS course_liked`);
}
Subquery를 안쓰고 바로 Likes테이블에서 Join을 했다.
이렇게 쉬운 거였는데!!!
다시 한번 기본기의 중요성을 깨달았다.
다시는 이런거로 시간 낭비 하지 말아야지.