DBGuide

SELECT 문 이해하기

📖 약 3🏷 SQL 기초

기본 문법

SELECT는 데이터베이스에서 데이터를 조회하는 명령입니다. 가장 많이 쓰는 SQL 명령이며, 복잡한 분석 쿼리도 결국 SELECT의 조합입니다.

SELECT column1, column2
FROM   table_name
WHERE  condition
ORDER BY column1 ASC
LIMIT  10;

SQL은 이렇게 작성하지만, 실제 실행 순서는 FROM → WHERE → SELECT → ORDER BY → LIMIT 입니다. 이 순서를 알면 "왜 SELECT에서 만든 별칭을 WHERE에서 못 쓰는지"가 이해됩니다 — WHERE가 먼저 실행되므로 아직 별칭이 없기 때문입니다.

열 선택

-- 모든 열 조회 (실무에서는 지양)
SELECT * FROM users;

-- 필요한 열만 명시 (권장)
SELECT id, name, email FROM users;

팁: SELECT *는 편하지만 불필요한 데이터까지 가져와 성능이 나빠질 수 있습니다. 특히 네트워크를 통해 대량 데이터를 전송하거나, 컬럼이 많은 테이블에서는 체감 차이가 큽니다. 항상 필요한 열만 명시하세요.

별칭 (Alias)

컬럼이나 테이블에 읽기 쉬운 이름을 붙일 수 있습니다.

-- 컬럼 별칭 (AS는 생략 가능)
SELECT
  u.name      AS user_name,
  u.email     AS contact_email,
  u.created_at AS joined_at
FROM users u;  -- 테이블 별칭: users를 u로

-- 계산식에도 별칭 사용
SELECT
  price,
  price * 0.1 AS vat,
  price * 1.1 AS total_with_vat
FROM products;

DISTINCT — 중복 제거

-- 중복 없이 도시 목록
SELECT DISTINCT city FROM users;

-- 여러 컬럼: 조합이 유일한 것만
SELECT DISTINCT city, country FROM users;

주의: DISTINCT는 전체 결과를 정렬해서 중복을 제거하므로 데이터가 많을수록 느립니다. 대량 데이터에서 유니크한 값 개수가 필요하다면 COUNT(DISTINCT column) 또는 집계 쿼리를 고려하세요.

WHERE로 필터링

-- 활성 사용자만 조회
SELECT id, name, email
FROM   users
WHERE  is_active = true;

-- 특정 기간 내 가입자
SELECT name, created_at
FROM   users
WHERE  created_at >= '2024-01-01'
  AND  created_at <  '2025-01-01';

ORDER BY로 정렬

-- 최신 가입자부터 (내림차순)
SELECT name, created_at
FROM   users
ORDER BY created_at DESC;

-- 이름 알파벳 순 (오름차순, 기본값)
SELECT name FROM users ORDER BY name ASC;

-- 여러 기준: 카테고리 오름차순, 가격 내림차순
SELECT name, category, price
FROM products
ORDER BY category ASC, price DESC;

팁: ORDER BY에서 컬럼 번호로 참조할 수 있습니다 (ORDER BY 2 DESC). 하지만 쿼리가 변경될 때 버그가 생길 수 있어서 컬럼명 명시를 권장합니다.

LIMIT & OFFSET

-- 첫 10명만
SELECT name FROM users LIMIT 10;

-- 11~20번째 (페이징)
SELECT name FROM users
ORDER BY id
LIMIT 10 OFFSET 10;

주의: OFFSET이 클수록 쿼리가 느려집니다. OFFSET 10000이면 10,010개를 읽고 10,000개를 버립니다. 대용량 페이징은 커서 기반 방식(WHERE id > :last_id)이 훨씬 효율적입니다. 자세한 내용은 고급 섹션의 "쿼리 최적화" 챕터에서 다룹니다.

계산 컬럼

SELECT 절에서 바로 계산할 수 있습니다.

SELECT
  name,
  price,
  stock,
  price * stock AS inventory_value,    -- 재고 가치
  ROUND(price * 0.1, 0) AS vat,        -- 부가세
  CASE
    WHEN stock = 0 THEN '품절'
    WHEN stock < 10 THEN '재고 부족'
    ELSE '정상'
  END AS stock_status
FROM products;

실전 예제: 게시글 목록

SELECT
  p.id,
  p.title,
  u.name AS author_name,
  p.created_at,
  p.view_count
FROM   posts p
JOIN   users u ON u.id = p.user_id
WHERE  p.is_published = true
ORDER BY p.created_at DESC
LIMIT  20;

이 쿼리가 이해된다면 SELECT 기초를 마스터한 겁니다. 다음은 WHERE 조건을 더 깊이 다룹니다.

댓글

... 으로 작성됩니다

댓글을 불러오는 중...