SQL 게시판 실습 복습 정리 | 쿼리 흐름 + 실행 결과 + 오답노트

JOPO·2025년 4월 16일
0

데이터베이스

목록 보기
7/7
post-thumbnail

이 문서는 시험에서 틀렸던 SQL 쿼리들을 복습하면서,
출력 항목 → 테이블 출처 → JOIN → 조건 → 정렬 기준 순서로 풀이 흐름을 정리했다.
다시 봤을 때 왜 그렇게 쿼리를 짰는지 흐름이 기억나도록 쿼리 위에 간단히 흐름을 덧붙였다.

짧은 소개글

오늘 시험에서 게시판 관련 SQL 문제를 풀었는데, 생각보다 시간이 부족해서 아쉬움이 좀 남았다. 전체적인 구조는 익숙했지만, JOIN 조건이 누락되거나 LEFT JOIN을 사용하지 않아서 결과가 달라진 경우가 있었고, 시험이 끝난 직후 곧바로 복습을 진행했다. 틀렸던 부분은 수정해서 다시 정리해봤다.


목차

  • 개념 정리
  • 비유 설명
  • 코드 및 풀이
  • 주의사항
  • 요약
  • 느낀점

개념 정리

테이블간단한 설명
member회원 정보 저장
board게시판 목록 관리
article게시물 정보 저장
articleReply댓글 정보 저장
like좋아요 기록 저장

테이블 구조 설명

  • member: 로그인 ID, 닉네임, 실명 같은 회원 정보를 저장한다. 게시글, 댓글, 좋아요에 전부 연결되는 핵심 테이블.
  • board: 게시판 이름을 저장하는 테이블. 자유게시판, 공지사항 등.
  • article: 실제 게시물 데이터를 담는다. 제목, 내용, 조회수, 작성자 등이 포함됨.
  • articleReply: 댓글을 저장. 어떤 게시물에 누가 댓글을 달았는지를 저장.
  • like: 어떤 회원이 어떤 게시물을 좋아요 했는지 저장. 복합키로 중복 방지.

비유 설명

  • member: 게시판에서 활동하는 사람 그 자체. 글을 쓰고 댓글을 달고 좋아요도 누르는 모든 주체가 이 테이블에 담겨 있다. 게시판 시스템에서 회원 정보를 나타내는 핵심 테이블로, 사용자 프로필 역할을 한다고 볼 수 있다.
  • board: 책장이 여러 개 있는 도서관의 책꽂이
  • article: 책꽂이에 꽂힌 책 한 권 한 권
  • articleReply: 책에 붙은 포스트잇 메모
  • like: 책에 찍힌 추천 도장

코드 및 풀이

1. 전체 게시물 수

❶ 출력: 게시물 수
❷ 출처: article
❸ JOIN: 없음
❹ 조건: 없음
❺ 정렬: 없음
SELECT COUNT(*)         -- 전체 행 개수(= 게시물 수)를 센다
FROM article;           -- 게시물 테이블에서

실행 결과 예시

게시물 수
10

2. 전체 조회수 합계

❶ 출력: 전체 조회수 합계
❷ 출처: article
❸ JOIN: 없음
❹ 조건: 없음
❺ 정렬: 없음
SELECT SUM(hit)         -- hit 컬럼의 값을 모두 더함 (조회수 총합)
FROM article;           -- 게시물 테이블에서

실행 결과 예시

조회수 총합
659

3. 자유게시판에서 '제' 포함 제목 검색

❶ 출력: 게시물 번호, 제목, 본문, 조회수, 닉네임, 작성일
❷ 출처: article, member, board
❸ JOIN: article → member, article → board
❹ 조건: 제목에 '제' 포함, 자유게시판
❺ 정렬: 작성일 내림차순
SELECT art.ano,         -- 게시물 번호
       art.title,       -- 제목
       art.`body`,      -- 본문 내용
       art.hit,         -- 조회수
       mem.nname,       -- 작성자 닉네임
       art.regDate      -- 작성일
FROM article AS art     -- 게시물 테이블
INNER JOIN `member` AS mem ON art.mno = mem.mno  -- 작성자 정보 연결
INNER JOIN board AS bo ON art.bno = bo.bno       -- 게시판 정보 연결
WHERE art.title LIKE '%제%'                      -- 제목에 '제' 포함 필터
  AND bo.bname = '자유게시판'                    -- 자유게시판만
ORDER BY art.regDate DESC;                       -- 작성일 기준 최신순 정렬

실행 결과 예시

게시물 번호제목내용조회수닉네임작성일시
1제목1내용110신출귀몰2020-03-03 12:30:00
2제목2내용223신출귀몰2021-05-06 15:12:00

4. 게시판별 게시물 수

❶ 출력: 게시판 이름, 게시물 수
❷ 출처: board, article
❸ JOIN: board → article (LEFT JOIN)
❹ 조건: 없음
❺ 정렬: 게시물 수 내림차순
SELECT bo.bname,                          -- 게시판 이름
       COUNT(art.ano) AS 게시물수         -- 게시물 개수
FROM board AS bo                          -- 게시판 테이블 기준
LEFT JOIN article AS art ON bo.bno = art.bno  -- 게시물 연결 (없어도 포함)
GROUP BY bo.bname                         -- 게시판 단위로 묶기
ORDER BY 게시물수 DESC;                  -- 게시물 많은 순으로 정렬

실행 결과 예시

게시판 이름게시물 수
자유게시판5
공지사항2
질문과답변3

5. 최근 반년 사이 게시물 조회

❶ 출력: 제목, 본문, 닉네임, 작성일
❷ 출처: article, member
❸ JOIN: article → member
❹ 조건: 날짜 BETWEEN 2023-10-01 AND 2024-04-01
❺ 정렬: 작성일 내림차순
SELECT art.title,                         -- 제목
       art.`body`,                        -- 본문
       mem.nname,                         -- 닉네임
       art.regDate                        -- 작성일
FROM article AS art                       -- 게시물 테이블
INNER JOIN `member` AS mem ON art.mno = mem.mno  -- 작성자 정보 연결
WHERE art.regDate BETWEEN '2023-10-01' AND '2024-04-01'  -- 날짜 조건
ORDER BY art.regDate DESC;               -- 최신순 정렬

실행 결과 예시

제목내용닉네임작성일시
제목9내용9힘쎈장사2024-03-03 23:12:00

6. 댓글 수 가장 많은 게시판

❶ 출력: 게시판 이름, 댓글 수
❷ 출처: board, article, articleReply
❸ JOIN: board → article → articleReply
❹ 조건: 없음
❺ 정렬: 댓글 수 내림차순, LIMIT 1
SELECT bo.bname,                          -- 게시판 이름
       COUNT(*) AS 댓글수                 -- 댓글 개수
FROM `board` AS bo                        -- 게시판 테이블
INNER JOIN article AS art ON bo.bno = art.bno        -- 게시물 연결
INNER JOIN `articleReply` AS re ON art.ano = re.ano  -- 댓글 연결
GROUP BY bo.bname                         -- 게시판 단위로 묶기
ORDER BY 댓글수 DESC                      -- 댓글 많은 순 정렬
LIMIT 1;                                  -- 상위 1개만

실행 결과 예시

게시판 이름댓글 수
자유게시판7

7. 게시물별 댓글 수

❶ 출력: 게시물 번호, 제목, 댓글 수
❷ 출처: article, articleReply
❸ JOIN: article → articleReply
❹ 조건: 없음
❺ 정렬: 댓글 수 내림차순, 같으면 게시물 번호 오름차순
SELECT art.ano,                           -- 게시물 번호
       art.title,                         -- 게시물 제목
       COUNT(*) AS 댓글수                 -- 댓글 개수
FROM article AS art                       -- 게시물 테이블
INNER JOIN `articleReply` AS re ON art.ano = re.ano  -- 댓글 연결
GROUP BY art.ano                          -- 게시물 단위로 묶기
ORDER BY 댓글수 DESC, art.ano ASC;       -- 댓글 많은 순, 같으면 번호 오름차순

실행 결과 예시

게시물 번호제목댓글 수
9제목95
8제목82
6제목63

8. 회원별 조회수 총합

❶ 출력: 회원번호, 닉네임, 조회수 총합
❷ 출처: member, article
❸ JOIN: member → article
❹ 조건: 없음
❺ 정렬: 조회수 총합 내림차순, 같으면 회원번호 오름차순
SELECT mem.mno,                           -- 회원 번호
       mem.nname,                         -- 닉네임
       SUM(hit) AS 조회수총합             -- 게시물 조회수 합계
FROM `member` AS mem                      -- 회원 테이블
INNER JOIN article AS art ON mem.mno = art.mno  -- 회원이 쓴 게시물 연결
GROUP BY mem.mno                          -- 회원 단위로 묶기
ORDER BY 조회수총합 DESC, mem.mno ASC;   -- 조회수 높은 순, 같으면 번호 오름차순

실행 결과 예시

회원 번호닉네임조회수 총합
1신출귀몰300

9. 조회수 상위 3개 게시물

❶ 출력: 제목, 본문, 닉네임, 조회수
❷ 출처: article, member
❸ JOIN: article → member
❹ 조건: 없음
❺ 정렬: 조회수 내림차순, LIMIT 3
SELECT art.title,                         -- 제목
       art.`body`,                        -- 본문
       mem.nname,                         -- 닉네임
       art.hit                            -- 조회수
FROM article AS art                       -- 게시물 테이블
INNER JOIN `member` AS mem ON art.mno = mem.mno  -- 작성자 정보 연결
ORDER BY art.hit DESC                     -- 조회수 높은 순 정렬
LIMIT 3;                                  -- 상위 3개만

실행 결과 예시

제목내용닉네임조회수
제목4내용4구국의 영웅100
제목7내용7구국의 영웅87
제목1내용1신출귀몰70

10. 좋아요 가장 많이 받은 회원

❶ 출력: 로그인 ID, 실명, 좋아요 수
❷ 출처: member, like
❸ JOIN: member → like
❹ 조건: 없음
❺ 정렬: 좋아요 수 내림차순, LIMIT 1
SELECT mem.loginId,                       -- 로그인 ID
       mem.rname,                         -- 실명
       COUNT(*) AS 좋아요개수             -- 좋아요 개수
FROM `member` AS mem                      -- 회원 테이블
INNER JOIN `like` AS li ON mem.mno = li.mno       -- 좋아요 기록 연결
GROUP BY mem.loginId, mem.rname          -- 회원 단위로 묶기
ORDER BY 좋아요개수 DESC                 -- 좋아요 많은 순 정렬
LIMIT 1;                                  -- 1명만 출력

실행 결과 예시

로그인 ID실명좋아요 개수
user4유관순5

주의사항

  • like는 SQL 예약어라 테이블명으로 쓸 땐 백틱(``)이 필요하다.
  • 게시물이 없는 게시판도 포함하려면 LEFT JOIN을 써야 한다.
  • 날짜 필터는 BETWEEN으로 명확히 구간 지정.
  • 정렬 없이 LIMIT만 쓰면 어떤 기준으로 잘렸는지 모를 수 있으니 ORDER BY와 함께 사용해야 정확한 결과를 얻을 수 있다.

요약

항목주의할 점해결 방법
like 테이블예약어 충돌백틱(`) 또는 이름 변경
게시판별 게시물 수게시물 없는 경우 누락LEFT JOIN 사용
날짜 비교범위 애매할 수 있음BETWEEN '시작' AND '끝' 사용
LIMIT 사용정렬 기준 없으면 불확실ORDER BY와 같이 사용
좋아요 많은 회원GROUP BY 후 정렬 빠짐ORDER BY COUNT(*) DESC 추가

느낀점

전체적으로 어렵진 않았는데, 쿼리 조건 하나 빠지면 결과가 완전히 달라져서 꼼꼼하게 읽는 연습이 필요하다고 느꼈다. 실수한 부분은 대부분 JOIN 조건이나 WHERE 조건이 부족해서 나온 결과였고, LEFT JOIN을 써야 하는 상황도 실습하면서 다시 떠올렸다. 특히 좋아요 많은 회원 찾는 문제에서 ORDER BY 없이 LIMIT만 쓴 실수는 꼭 기억해둬야겠다. 다음엔 처음부터 문제 조건을 더 명확히 분석하고, 쿼리를 짜기 전에 어떤 테이블이 어떤 관계인지 생각하고 시작해야겠다.

0개의 댓글