목표
도서구매사이트에서 개별 도서 조회 시 다음 정보를 가져오는 SQL 쿼리입니다:
- books 테이블의 도서 기본 정보
- category 테이블의 카테고리 이름
- 해당 도서의 likes 수 (다른 테이블에서 count)
SQL 예시 (서브쿼리 방식)
// '개별' 도서 조회
async function selectEachBook(req, res) {
try {
const {user_id} = req.body;
const {book_id} = req.params;
const conn = await dbConnection;
let sql = `
SELECT
book_store.books.*,
book_store.category.name AS category_name,
( SELECT EXISTS
(
SELECT * FROM likes WHERE likes.user_id = ? AND likes.book_id = ?
)
) AS isLiked
FROM book_store.books
LEFT JOIN book_store.category
ON book_store.books.categoryId = book_store.category.id
WHERE books.id = ?
`;
const sqlValues = [user_id, book_id, book_id]
const [result] = await conn.query(sql, sqlValues);
console.log("result : ",result);
res.status(StatusCodes.OK).json({
message : "개별 도서 조회",
data : result
})
}
catch (err) {
console.error(err);
res.status(StatusCodes.INTERNAL_SERVER_ERROR).json({
message : "서버 에러",
error : err
});
}
}
핵심 개념 설명
1. COUNT(*)
- 특정 조건을 만족하는 행(row)의 개수를 세는 집계 함수
- 여기선 likes 테이블에서 해당 책에 대한 좋아요 수를 세는 역할
SELECT COUNT(*) FROM likes WHERE book_id = 5;
-- book_id가 5인 행의 개수를 반환 (예: 7)
2. AS
- **별칭(alias)**을 설정하는 키워드
- 결과 컬럼 이름을 like_count로 정함
COUNT(*) AS like_count
-- 결과 컬럼명이 like_count가 됨
- 실제 응답에서는 이렇게 출력됨:
{
"id": 12,
"title": "노드 입문",
"category_name": "개발",
"like_count": 7
}
3. 서브쿼리(Subquery)
- SELECT문 안에 또 다른 SELECT문을 넣는 것
- 여기서는 SELECT COUNT(*) FROM likes ...가 books 테이블의 각 행마다 실행되는 쿼리로 사용됨
- 개별 도서마다 해당 도서의 book_id에 해당하는 좋아요 수를 계산
(
SELECT COUNT(*)
FROM likes
WHERE likes.book_id = books.id
)
- 이 서브쿼리의 결과가 like_count라는 이름으로 최종 결과에 포함됨
정리
| 요소 | 설명 |
| COUNT(*) | 조건에 맞는 행의 개수를 세는 집계 함수 |
| AS | 컬럼 또는 테이블에 별칭을 지정 |
| 서브쿼리 | 쿼리문 안에 들어있는 또 다른 SELECT문. 특정 컬럼 값을 동적으로 계산할 때 사용 |
최종 정리 요약
SELECT ... FROM books 구문에서 서브쿼리로 좋아요 수를 조회하고,
COUNT(*)를 사용해 좋아요 수를 계산,
AS를 사용해 결과에 'like_count'라는 이름으로 표시합니다.
'mariaDB > 3. SQL 사용법' 카테고리의 다른 글
| IN (?, ?, ?) 문법 (0) | 2025.05.20 |
|---|---|
| EXISTS 문법 (0) | 2025.05.19 |
| 두 컬럼의 값을 한 쌍으로 제약조건 만들기 (0) | 2025.05.19 |
| 데이터베이스 페이징 (1) | 2025.05.16 |
| SQL 시간 범위 구하기 (DATE_ADD, SUB) (0) | 2025.05.16 |