🐨CoalaCoding
DocsExamplesTry itBoardB반B반
🐨CoalaCoding

개발자를 위한 한국어 웹 기술 문서

문서

  • JavaScript
  • Web Publishing
  • React
  • Python

커뮤니티

  • 게시판
  • 예제 모음
  • Try it 에디터

기타

  • GitHub
  • 관리자
© 2026 CoalaCoding. All rights reserved.
  • sqlite3로 SQL 명령문 실행
  • DB데이터 일괄추가하기
  • SQLite3 라이브러리를 활용한 SQL 명령문 실행
  • Pandas를 활용한 SQL 명령문 실행
  • CREATE 명령어를 활용한 DB 테이블의 생성
  • DDL 명령어의 이해 및 실습
  • SQL SELECT 명령어의 이해 및 실습
  • SQL INSERT, UPDATE, DELETE 명령어 실습
  • SQL SELECT 세부 명령어 실습 1
  • SQL SELECT 세부 명령어 실습 2
  • SQL INNER JOIN 실습
  • SQL LEFT JOIN 실습
  • SQL GROUP BY 실습 1
  • SQL GROUP BY 실습 2
  • SQL SubQuery 활용 실습
  • 데이터셋 기반 DB 구축 & DB 활용 실습 — 리액트 연동 완성
  1. 홈
  2. 문서
  3. Backend
  4. Database & SQL
  5. SQL SELECT 세부 명령어 실습 1

SQL SELECT 세부 명령어 실습 1

코드 블록의 Try it Yourself 버튼으로 직접 실행할 수 있다.

구문

1. 인트로

SELECT의 강력한 세부 기능인 ORDER BY(오더 바이), DISTINCT(디스팅트), LIKE(라이크), IN(인)을 깊이 있게 익힌다. 이 기능들로 원하는 데이터를 정확하게 추출하는 능력을 키운다.


2. 실습 DB 준비

import sqlite3
import pandas as pd

conn = sqlite3.connect("webtoon.db")
cur  = conn.cursor()

cur.execute("""
    CREATE TABLE IF NOT EXISTS webtoons (
        id        INTEGER PRIMARY KEY AUTOINCREMENT,
        title     TEXT    NOT NULL,
        author    TEXT,
        genre     TEXT,
        platform  TEXT,
        score     REAL,
        views     INTEGER,
        complete  INTEGER DEFAULT 0
    )
""")

webtoons = [
    ("나 혼자만 레벨업",  "추공",  "액션",  "카카오페이지", 9.8, 50000000, 1),
    ("전지적 독자 시점", "싱숑",  "판타지", "카카오페이지", 9.7, 45000000, 1),
    ("신의 탑",        "SIU",  "판타지", "네이버웹툰",  9.5, 40000000, 0),
    ("외모지상주의",    "박태준", "드라마",  "네이버웹툰",  9.2, 60000000, 0),
    ("마스크걸",       "마일",  "스릴러", "네이버웹툰",  8.9, 20000000, 1),
    ("재혼황후",       "알파타르트", "로맨스", "카카오페이지", 9.1, 35000000, 1),
    ("입학용병",       "이 일규", "액션",  "네이버웹툰",  8.7, 18000000, 1),
    ("화산귀환",       "비가",  "무협",   "카카오페이지", 9.6, 42000000, 0),
    ("역대급 영지",    "야유",  "판타지", "네이버웹툰",  8.5, 12000000, 0),
    ("쌉니다 천리마마트","김규삼","드라마",  "네이버웹툰",  9.0, 22000000, 1),
]

cur.executemany(
    "INSERT INTO webtoons (title,author,genre,platform,score,views,complete) VALUES (?,?,?,?,?,?,?)",
    webtoons
)
conn.commit()
print("웹툰 데이터 삽입 완료")

3. ORDER BY(오더 바이) 정렬 실습

3.1. 단일 기준 정렬

# 조회수 높은 순으로 정렬
df = pd.read_sql(
    "SELECT title, views FROM webtoons ORDER BY views DESC",
    conn
)
print(df)

3.2. 다중 기준 정렬

# 장르 오름차순, 같은 장르 내에서는 점수 내림차순
df = pd.read_sql(
    "SELECT title, genre, score FROM webtoons ORDER BY genre ASC, score DESC",
    conn
)
print(df)

코드 설명:

  • 3행: ORDER BY genre ASC, score DESC — 먼저 genre로 정렬하고, 같은 genre 내에서는 score 내림차순으로 정렬한다.
  • 콤마(,)로 여러 정렬 기준을 지정할 수 있다.

4. DISTINCT(디스팅트)를 활용한 중복 제거 실습

4.1. 중복 없이 플랫폼 목록 조회

cur.execute("SELECT DISTINCT platform FROM webtoons")
platforms = cur.fetchall()
print("=== 플랫폼 목록 ===")
for p in platforms:
    print(f"  - {p[0]}")

실행 결과:

=== 플랫폼 목록 ===
  - 카카오페이지
  - 네이버웹툰

코드 설명:

  • 1행: SELECT DISTINCT platform — platform 컬럼에서 중복을 제거한 고유값만 가져온다.
  • DISTINCT가 없으면 같은 플랫폼 이름이 여러 번 반복된다.

4.2. 다중 컬럼 DISTINCT

# 장르와 플랫폼 조합의 중복 제거
df = pd.read_sql(
    "SELECT DISTINCT genre, platform FROM webtoons ORDER BY genre",
    conn
)
print(df)

코드 설명:

  • 두 컬럼 모두 동일한 행만 중복으로 처리된다. 장르가 같아도 플랫폼이 다르면 별개의 행으로 간주한다.

5. WHERE 절에서의 LIKE & IN 적용 실습

5.1. LIKE(라이크) — 패턴 검색

# 제목에 '황'이 포함된 웹툰 검색
cur.execute("SELECT title, author FROM webtoons WHERE title LIKE '%황%'")
rows = cur.fetchall()
print("=== '황' 포함 웹툰 ===")
for r in rows:
    print(f"  {r[0]} - {r[1]}")
# 저자명이 두 글자인 작가 검색 (_는 글자 하나를 의미)
cur.execute("SELECT title, author FROM webtoons WHERE author LIKE '__'")
rows = cur.fetchall()
print("=== 두 글자 작가 ===")
for r in rows:
    print(f"  {r[0]} - {r[1]}")

코드 설명:

  • % — 0개 이상의 임의 문자
  • _ — 정확히 1개의 임의 문자
  • LIKE '__' — 정확히 2글자인 값을 찾는다.

5.2. IN(인) — 여러 값 중 하나

# 액션 또는 판타지 장르만 조회
cur.execute("""
    SELECT title, genre, score
    FROM webtoons
    WHERE genre IN ('액션', '판타지')
    ORDER BY score DESC
""")
rows = cur.fetchall()
print("=== 액션/판타지 웹툰 ===")
for r in rows:
    print(f"  [{r[1]}] {r[0]} : {r[2]}")

코드 설명:

  • 5행: IN ('액션', '판타지') — genre가 '액션' 이거나 '판타지'인 행을 가져온다.
  • IN은 여러 개의 OR 조건을 간결하게 표현한다. WHERE genre = '액션' OR genre = '판타지'와 동일하다.

5.3. NOT IN(낫 인) — 제외

# 네이버웹툰이 아닌 플랫폼의 웹툰 조회
df = pd.read_sql(
    "SELECT title, platform FROM webtoons WHERE platform NOT IN ('네이버웹툰')",
    conn
)
print(df)

코드 설명:

  • NOT IN — 괄호 안의 값 목록에 포함되지 않는 행을 가져온다.

6. 복합 조건 실전 실습

# 완결된 판타지 또는 액션 웹툰 중 점수 9.0 이상
df = pd.read_sql("""
    SELECT title, genre, score, platform
    FROM webtoons
    WHERE complete = 1
      AND genre IN ('판타지', '액션')
      AND score >= 9.0
    ORDER BY score DESC
""", conn)
print("=== 완결 인기 웹툰 ===")
print(df)

코드 설명:

  • 5행: complete = 1 — 완결 웹툰만 선택한다.
  • 6행: IN ('판타지', '액션') — 두 장르 중 하나인 것만 선택한다.
  • 7행: score >= 9.0 — 점수 9.0 이상인 것만 선택한다.
  • AND로 세 조건을 모두 만족하는 행만 가져온다.

7. 활용 Plus — 리액트 연동 관점

리액트 웹툰 앱에서 "장르 필터 + 정렬" 기능을 구현할 때, 파이썬 API는 아래와 같이 동작한다.

def get_webtoons(genre=None, order="score"):
    base_sql = "SELECT title, genre, score, platform FROM webtoons"
    params   = []
    if genre:
        base_sql += " WHERE genre = ?"
        params.append(genre)
    base_sql += f" ORDER BY {order} DESC"
    cur.execute(base_sql, params)
    return cur.fetchall()

# 사용 예
result = get_webtoons(genre="판타지", order="score")
for r in result:
    print(r)

코드 설명:

  • 1행: 장르와 정렬 기준을 함수 인자로 받아 동적으로 SQL을 구성한다.
  • 4~6행: 장르가 지정된 경우에만 WHERE 절을 추가한다.
  • 이 패턴이 실제 리액트 앱의 필터 기능 API 코드이다.

8. 문제풀기

Q1. DISTINCT의 역할은?

조회 결과에서 중복된 값을 제거하고 고유한 값만 반환한다.

Q3. IN 연산자를 사용하는 이유는?

여러 OR 조건을 간결하게 표현하기 위해서이다. WHERE genre='액션' OR genre='판타지'를 WHERE genre IN ('액션','판타지')로 단축할 수 있다.

Q4. ORDER BY genre ASC, score DESC의 의미를 설명하시오.

먼저 genre를 알파벳/가나다 오름차순으로 정렬하고, 같은 genre 안에서는 score를 높은 순(내림차순)으로 다시 정렬한다.

목차

  • 구문