이번 강의에서는 도서별 좋아요 갯수와 로그인한 사용자의 좋아요 여부를 위해 서브쿼리 를 사용했다.
도서 테이블 + 좋아요 테이블
사용자 테이블 + 좋아요 테이블 + 책 테이블
이런식으로 결론적으로 사용했는데 어떻게 사용했는지 살펴보자.

서브 쿼리란 다른 쿼리 내부에 포함되어 있는 SELECT문 을 의미한다.
즉 바깥쪽 쿼리인 외부쿼리안에 서브쿼리를 넣어서 사용하면 된다.
1. 외부 쿼리 작성
2. 외부 쿼리 안에 내부 쿼리 작성
전체적으로 보면 외부쿼리 : 도서 검색 , 내부쿼리 : 좋아요 갯수라고 볼 수 있다.
SELECT * FROM books;
우선 좋아요 갯수를 세는 것이기 때문에 집계함수중 COUNT()를 사용했다
SELECT COUNT(*) AS "좋아요 갯수" FROM likes;
여기서 도서별 좋아요 갯수기 때문에 특정 도서를 찾는 조간문을 넣어줘야 한다.
좋아요 테이블의 ID와 책 테이블의 ID가 같은 경우
참고로 둘의 FK로 이어져 있다.
SELECT COUNT(*) AS "좋아요 갯수" FROM likes
WHERE liked_book_id = books.id;
따라서 서브 쿼리의 최종 코드는 다음과 같이 된다.
SELECT *,
(SELECT COUNT(*) FROM likes WHERE liked_book_id = books.id) AS '좋아요 갯수'
FROM books
외부 쿼리의 SELECT과 FROM 사이에 서브 쿼리를 넣으면 되고
서브 쿼리는 반드시 '( )'로 묶어줘야 한다
앞서 언급한 대로 이번 로직은 사용자 , 책 , 좋아요 테이블이 필요하다.
SELECT * FROM books WHERE books.id = ? ;
이것도 결국엔 책을 SELECT 하는 것이기 때문에 책 테이블 검색이 외부 쿼리이다.
SELECT EXISTS
(SELECT * FROM likes WHERE user_id = ? AND liked_book_id = ?)) AS '좋아요 여부'
FROM books
좋아요 테이블엔 books 테이블의 id값과 users 테이블의 id값만 가진다.
즉 어떤 사용자가 어떤 책의 좋아요를 눌렀는지에 대한 정보를 가지고 있다.
따라서 존재 여부를 알려주는 EXISTS()를 사용해 존재 하면 1 , 존재하지 않으면 0으로 표시해 사용자가 좋아요를 눌렀는지 알 수 있다!!
SELECT *,
(SELECT EXISTS
(SELECT * FROM likes WHERE user_id = ? AND liked_book_id = ?)) FROM books) AS '좋아요 여부'
WHERE books.id = ?;
이번엔 조건이 많아져 살짝 복잡해졌는데
그래도 기본적인 서브쿼리를 사용하는 방법은 똑같다.
다른 프로젝트에서 좋아요 여부 로직을 구현해본적이 있는데
그 당시엔 좋아요 테이블을 따로 만들지 않고 외부 테이블 좋아요 속성에
배열로 좋아요한 사용자 id 값을 받고 로그인한 사용자 id와 배열에 들어간 id 값을 비교하여 좋아요 여부를 체크했었다.
나중에 찾아보니 내가 한 방법은 반정규화의 방법으로 데이터의 무결성 문제와 배열에 매번 접근해야 하다보니 비효율적이라고 한다 ㅜㅜ
그 당시엔 이 정규화 방법에 대해 몰랐지만 지금이라도 알 게 되어 또 하나 얻어가게 되었다 ㅎㅎ