Pulling Data Out With SELECT
한국어 원문으로 표시합니다.
목표
PostgreSQL 에 직접 접속해 SELECT, WHERE, DISTINCT, ORDER BY 로 원하는 행만 골라내고, 그 결과를 뷰로 저장할 수 있게 됩니다.
왜 중요한가
SQL 은 명령형이 아니라 선언형입니다. "이 파일을 열고 한 줄씩 읽어 비교하라"가 아니라 "이런 조건을 만족하는 행을 달라"고 적으면, 어떻게 찾을지는 데이터베이스가 그때의 통계를 보고 정합니다. 그래서 SQL 을 잘 쓴다는 것은 원하는 집합을 정확히 서술하는 능력이지 빠른 알고리즘을 아는 능력이 아닙니다.
이 실습에서 특히 눈여겨볼 것은 NULL 입니다. NULL 은 "값이 없다"가 아니라 "모른다"에 가까워서, 어떤 값과 비교해도 참이 되지 않습니다. 이 성질 하나가 조회, 집계, 조인 전반에 파급되므로 지금 손으로 확인해 두는 편이 좋습니다.
뷰로 저장하는 이유도 있습니다. 뷰는 결과를 복사해 두는 것이 아니라 질의 자체에 이름을 붙이는 것이라, 원본이 바뀌면 뷰의 결과도 따라 바뀝니다. 채점 스크립트가 여러분이 만든 뷰를 원본과 대조하는 것도 이 성질 덕분입니다.
단계
customers테이블의 전체 행 수를 세어 그 숫자만/root/rowcount.txt에 저장합니다.is_active가 참인 고객만 담는 뷰v_active_customers를 만듭니다. 컬럼은 원본 그대로 둡니다.country가KR이면서tier가gold인 고객만 담는 뷰v_kr_gold를 만듭니다.email이 비어 있는 고객만 담는 뷰v_missing_email을 만듭니다.products의category를 중복 없이 담는 뷰v_categories를 만듭니다. 컬럼은category하나뿐이어야 합니다.is_active가 참이면서price가 200000 이상인 상품을 담는 뷰v_expensive를 만듭니다.ordered_at이TIMESTAMPTZ '2025-07-01 00:00:00+09'이후(같은 값 포함)인 주문을 담는 뷰v_recent_orders를 만듭니다.country가KR이고is_active가 참인 고객의id,name,tier를 이 순서로 담는 뷰v_kr_report를 만듭니다. 정렬은tier오름차순, 같으면id오름차순입니다.
참고
- 접속:
psql -h 127.0.0.1 -U lab -d labdb(비밀번호는lab, 환경변수PGPASSWORD를 쓰면 편합니다) - 테이블 목록은
\dt, 컬럼 구조는\d customers로 볼 수 있습니다. - 파일로 값만 뽑을 때는
psql -tAc "select ..." > 파일형태가 편합니다. - 흔한 실수 1:
WHERE email = NULL은 오류도 나지 않고 그냥 0행을 돌려줍니다. - 흔한 실수 2: 뷰를 다시 만들 때는
CREATE OR REPLACE VIEW를 쓰되, 컬럼 개수나 이름이 달라지면 먼저DROP VIEW해야 합니다.
고객 수 세어 보기
customers 테이블의 전체 행 수를 세어 그 숫자만 /root/rowcount.txt 에 저장합니다.
행 수를 세는 집계 함수와, psql 의 결과만 뽑아 주는 옵션(-t, -A)을 조합하면 파일에 숫자만 남길 수 있습니다.
활성 고객 뷰 만들기
is_active 가 참인 고객만 담는 뷰 v_active_customers 를 만듭니다. 컬럼은 원본 그대로 둡니다.
boolean 컬럼은 = true 를 붙이지 않고 조건에 그대로 쓸 수 있습니다. 뷰는 CREATE VIEW 이름 AS SELECT ... 형태입니다.
두 조건을 함께 걸기
country 가 KR 이면서 tier 가 gold 인 고객만 담는 뷰 v_kr_gold 를 만듭니다.
조건 두 개를 모두 만족해야 하므로 AND 로 묶습니다. 문자열 비교는 대소문자를 구분합니다.
이메일이 없는 고객 찾기
email 이 비어 있는 고객만 담는 뷰 v_missing_email 을 만듭니다.
NULL 은 어떤 값과 비교해도 참이 되지 않습니다. 등호 대신 전용 연산자가 필요합니다.
카테고리 목록 뽑기
products 의 category 를 중복 없이 담는 뷰 v_categories 를 만듭니다. 컬럼은 category 하나뿐이어야 합니다.
중복을 없애는 키워드를 SELECT 바로 뒤에 붙입니다. 결과 컬럼은 하나여야 하니 다른 컬럼을 넣지 마세요.
판매 중인 고가 상품 찾기
is_active 가 참이면서 price 가 200000 이상인 상품을 담는 뷰 v_expensive 를 만듭니다.
가격 조건과 판매 여부 조건을 모두 걸어야 합니다. 20만원 이상이므로 경계값을 포함합니다.
특정 시점 이후 주문 고르기
ordered_at 이 TIMESTAMPTZ '2025-07-01 00:00:00+09' 이후(같은 값 포함)인 주문을 담는 뷰 v_recent_orders 를 만듭니다.
ordered_at 은 시간대를 포함한 타입입니다. 비교 값에도 시간대를 명시해야 서버 설정과 무관하게 같은 결과가 나옵니다.
보고서용 뷰로 마무리하기
country 가 KR 이고 is_active 가 참인 고객의 id, name, tier 를 이 순서로 담는 뷰 v_kr_report 를 만듭니다. 정렬은 tier 오름차순, 같으면 id 오름차순입니다.
필요한 컬럼만 고르고 별칭을 맞추세요. 정렬 기준이 두 개일 때는 ORDER BY 에 쉼표로 나열합니다.