SQL SELECT 문은 표에서 보고 싶은 열을 골라 꺼내는 문장입니다. SELECT 뒤에 열 이름을, FROM 뒤에 표 이름을 적으면 되는데요, 여기에 별칭(AS)과 중복 빼기(DISTINCT), 계산 열까지 알면 원본 표를 건드리지 않고도 보고서에 필요한 모양을 꽤 많이 만들 수 있습니다.
저도 SQL 을 처음 배우면서 「일단 SELECT * 로 다 꺼내 놓고 보면 되지 않나?」라고 생각했는데요, 이번 글에서는 SELECT·FROM 의 기본형부터 * 를 아껴 써야 하는 이유, 열 이름을 바꾸고 계산하는 법까지 예시 표로 직접 따라 해 보겠습니다. 쿼리는 BigQuery(GoogleSQL) 문법으로 적었습니다.
지난 글: SQL 이란? 명령어 종류와 쿼리가 실행되는 순서
SQL 기초 시리즈 6/12 · 전체 커리큘럼
오늘 배울 개념
지난 글에서 SELECT 문은 FROM 부터 읽힌다고 했죠. 오늘은 그 두 절만 떼어 보는데요, FROM 은 「어느 표에서」, **SELECT 는 「어떤 열을 보여 줄지」**를 정합니다. BigQuery 쿼리 문법 문서도 SELECT 목록을 「쿼리가 돌려줄 열을 정하는 곳」이라고 설명합니다. 엑셀로 치면 열 숨기기와 비슷합니다. 주문 시트에 열이 열 개 있어도 보고서에는 날짜·채널·금액 세 열만 보이면 충분할 때가 많은데요, 엑셀은 나머지 열을 숨기거나 지우지만 SQL 은 원본 표는 그대로 두고 고른 열만 담은 새 결과 표를 돌려줍니다. 원본을 실수로 망가뜨릴 걱정이 없는 셈이죠.
따라 해 보기: SQL SELECT 문으로 열 고르기
문구점 주문 표 shop.orders 를 쓰겠습니다(가상 데이터). shop 은 데이터셋 이름, orders 는 표 이름인데요, BigQuery 문법 문서의 예시처럼 표 이름 앞에 데이터셋을 붙여 데이터셋.표 로 적습니다.
orders
| order_id | order_date | channel | product | unit_price | quantity |
|---|---|---|---|---|---|
| 1 | 2026-11-02 | 검색광고 | 볼펜 | 1500 | 4 |
| 2 | 2026-11-02 | SNS | 노트 | 3000 | 2 |
| 3 | 2026-11-03 | 검색광고 | 노트 | 3000 | 1 |
| 4 | 2026-11-03 | 이메일 | 볼펜 | 1500 | 10 |
| 5 | 2026-11-04 | SNS | 노트 | 3000 | 3 |
| 6 | 2026-11-05 | 검색광고 | 형광펜 | 2000 | 5 |
1. 필요한 열만 꺼내기: 열 이름을 쉼표로 이어 적고, FROM 뒤에 표를 적습니다.
SELECT order_id, channel, product
FROM shop.orders;| order_id | channel | product |
|---|---|---|
| 1 | 검색광고 | 볼펜 |
| 2 | SNS | 노트 |
| 3 | 검색광고 | 노트 |
| 4 | 이메일 | 볼펜 |
| 5 | SNS | 노트 |
| 6 | 검색광고 | 형광펜 |
행은 6개 그대로이고 열만 세 개로 줄었습니다. 결과 표의 열 순서는 원본이 아니라 SELECT 에 적은 순서를 따르는데요, 위 결과의 행 순서는 보기 좋게 원본 순서대로 적었을 뿐이고 ORDER BY 가 없으면 행 순서는 정해져 있지 않다는 점을 지난 글에서 짚었죠.
개념 그림: FROM 으로 표를 정하고, SELECT 로 고른 열만 새 결과 표에 담깁니다
2. 계산 열과 별칭(AS): SELECT 목록에는 열 이름뿐 아니라 계산식도 쓸 수 있습니다. 단가와 수량을 곱해 주문 금액을 만들고 AS 로 이름을 붙여 보겠습니다.
SELECT
order_id,
product,
unit_price * quantity AS amount
FROM shop.orders;| order_id | product | amount |
|---|---|---|
| 1 | 볼펜 | 6000 |
| 2 | 노트 | 6000 |
| 3 | 노트 | 3000 |
| 4 | 볼펜 | 15000 |
| 5 | 노트 | 9000 |
| 6 | 형광펜 | 10000 |
amount 는 원본 표에 없는 열인데요, 행마다 계산해 결과에만 붙은 열이라 원본은 바뀌지 않습니다. BigQuery 연산자 문서의 결과 타입 표를 보면 두 열이 INT64(정수)일 때 곱하면 INT64 가 되고, INT64 끼리 나누면 FLOAT64 가 되는데요, 금액을 나눌 때 소수점이 붙어 나오는 이유가 여기에 있습니다.
개념 그림: 계산 열에 AS 로 이름표를 붙여야 뒤에서 그 이름으로 부를 수 있습니다
3. DISTINCT 로 중복 빼기: 「어떤 채널에서 주문이 들어왔나」만 알고 싶을 때는 DISTINCT 를 씁니다. 문법 문서에 따르면 SELECT DISTINCT 는 중복된 행을 버리고 남은 행만 돌려줍니다.
SELECT DISTINCT channel
FROM shop.orders;| channel |
|---|
| 검색광고 |
| SNS |
| 이메일 |
여기서 중복 판단은 SELECT 에 적은 열 전체의 조합으로 합니다. SELECT DISTINCT channel, product 로 바꾸면 (SNS, 노트) 조합만 2번·5번 주문에서 겹쳐 한 줄로 합쳐지고, 나머지 다섯 조합이 남습니다.
| channel | product |
|---|---|
| 검색광고 | 볼펜 |
| SNS | 노트 |
| 검색광고 | 노트 |
| 이메일 | 볼펜 |
| 검색광고 | 형광펜 |
개념 그림: DISTINCT 는 SELECT 에 적은 열 조합이 같은 행을 한 줄만 남깁니다
4. FROM 없이 계산만 하기: 문법 문서의 SELECT 구문에서 FROM 은 대괄호로 묶인 「생략 가능한 절」인데요, 그래서 표 없이 계산기처럼 쓸 수도 있습니다.
SELECT 1500 * 4 AS amount;| amount |
|---|
| 6000 |
계산식이 맞는지 표에 넣기 전에 따로 확인해 볼 때 쓸모가 있습니다. 다만 PostgreSQL SELECT 문서에 따르면 다른 DBMS 중에는 FROM 을 생략하지 못하고 한 행짜리 임시 표를 따로 둬야 하는 제품도 있습니다. 위 결과 표의 값은 모두 예시 표가 작아 손으로 계산해 맞춘 값입니다.
SELECT * 는 언제 써도 되고 언제 피해야 할까요?
SELECT * 는 「보이는 모든 열」을 꺼내는 별표(select star) 문법입니다. 처음 보는 표의 모양을 확인할 때는 편하지만, 보고서에 들어갈 쿼리라면 열을 직접 적는 편이 안전한데요, 이유는 두 문서에서 찾을 수 있습니다.
- 표가 바뀌면 결과도 따라 바뀝니다: Microsoft Learn 의 SQL 입문 과정은
SELECT *가 빠른 테스트에는 괜찮지만, 표에 열이 추가되거나 순서가 바뀌면 그대로 결과에 반영돼 그 쿼리를 쓰는 보고서가 예상과 다른 결과를 받을 수 있다고 설명합니다. - 필요 없는 열까지 읽습니다: 같은 과정은 필요 없는 데이터를 돌려주면 쿼리가 느려질 수 있다고 적고, BigQuery 성능 권장사항 문서도 「필요한 열만 조회하라」며 불필요한 열을 읽으면 그만큼 입출력이 낭비된다고 안내합니다. 같은 문서에 따르면
SELECT *에 LIMIT 를 붙여도 읽는 데이터 양은 줄지 않습니다.
BigQuery 에는 「거의 다 필요한데 몇 개만 빼고 싶을 때」 쓰는 SELECT * EXCEPT 도 있습니다. 문법 문서 설명대로 괄호 안에 적은 열만 결과에서 빠지는데요, 아래 쿼리는 order_date 를 뺀 다섯 열을 돌려줍니다.
SELECT * EXCEPT (order_date)
FROM shop.orders;세 방식을 나란히 놓으면 이렇습니다.
| 방식 | 결과 열 | 표에 열이 늘면 | 이럴 때 |
|---|---|---|---|
| 열 이름을 직접 적기 | 적은 열만, 적은 순서대로 | 결과는 그대로 | 보고서·대시보드에 들어갈 쿼리 |
SELECT * | 모든 열 | 새 열이 결과에 끼어든다 | 처음 보는 표의 모양 확인 |
SELECT * EXCEPT (...) | 뺀 열을 제외한 모두 | 새 열이 결과에 끼어든다 | 열이 많고 몇 개만 빼면 될 때 |
EXCEPT 도 별표를 쓰는 방식이라 표가 바뀌면 결과가 같이 바뀐다는 점은 * 와 같습니다. 그래서 저는 「한 번 보고 버릴 쿼리면 별표, 다시 쓸 쿼리면 열 이름」을 기준으로 삼으려 하는데요, 그렇다면 실무 쿼리에서는 열을 어떤 순서로 골라 적으면 될까요?
실무에서는 어떻게 쓸까요? 주간 보고용 열 뽑기
매주 월요일 채널별 주문 내역을 보고하는 담당자를 떠올려 보겠습니다. 보고서에 필요한 것은 주문일·채널·상품·금액 네 칸뿐인데요, 원본 표에는 단가와 수량이 따로 있고 금액 열은 없습니다.
- FROM 부터 정합니다: 어느 표에 원하는 값이 있는지 확인하고
FROM shop.orders를 적습니다. - 보고서 열 순서대로 SELECT 를 씁니다:
order_date, channel, product를 보고서 칸 순서대로 적습니다. - 없는 열은 계산해 만듭니다:
unit_price * quantity AS amount로 금액 열을 붙입니다. - 이름은 보고서와 맞춥니다: 받는 사람이 알아보기 쉽게 별칭을 정하는데요, 공백이나 하이픈이 든 이름을 쓰려면 어휘 구조 문서대로 백틱 기호로 감싸야 해서, 영문·숫자·밑줄로 짓는 편이 덜 번거롭습니다.
SELECT
order_date,
channel,
product,
unit_price * quantity AS amount -- 금액 = 단가 × 수량
FROM shop.orders;-- 뒤는 쿼리가 무시하는 주석인데요, 어휘 구조 문서에 따르면 -- 와 #, /* */ 를 주석으로 쓸 수 있습니다. 계산 열 옆에 계산 근거를 적어 두면 다음 주의 내가 덜 헷갈리겠죠. 다음 회차에서 WHERE 로 「지난주 주문만」 거르는 조건을 붙이면 이 쿼리가 그대로 주간 보고 쿼리가 됩니다.
다른 DBMS 에서는 문자열을 이어 붙이는 방식이 다른데요, BigQuery 는 || 연산자(또는 CONCAT 함수)를 쓰고, T-SQL 문자열 연결 문서에 따르면 SQL Server 는 + 로 문자열을 잇습니다.
연습 문제
1. (쉬움) shop.orders 에서 주문 번호와 주문일만 꺼내는 쿼리를 써 보세요.
정답 보기
SELECT order_id, order_date
FROM shop.orders;6행, 2열(order_id, order_date)이 나옵니다. 열 사이 쉼표와 FROM 뒤 표 이름만 맞으면 됩니다.
2. (보통) 이 표에서 팔린 상품의 종류만 중복 없이 보는 쿼리를 쓰고, 결과가 몇 행인지 답해 보세요.
정답 보기
SELECT DISTINCT product
FROM shop.orders;볼펜(1·4번), 노트(2·3·5번), 형광펜(6번)이라 3행입니다. DISTINCT 없이 쓰면 6행이 그대로 나옵니다.
3. (보통) 아래 쿼리를 실행하면 결과 열은 몇 개이고, 열 이름은 무엇일까요?
SELECT order_id product, quantity
FROM shop.orders;정답 보기
열은 2개이고 이름은 product, quantity 입니다. order_id 와 product 사이에 쉼표가 없어서, AS 를 생략한 별칭으로 읽혀 「order_id 값을 product 라는 이름으로 보여 달라」는 뜻이 되기 때문입니다. 그래서 product 열에는 상품명이 아니라 1부터 6까지의 주문 번호가 들어 있습니다.
자주 하는 실수
- 쉼표를 빠뜨려 열이 별칭이 됩니다: 문법 문서의 SELECT 항목 구문은
expression [ [ AS ] alias ]로,AS를 생략해도 별칭이 됩니다. 연습 문제 3번처럼 오류 없이 엉뚱한 결과가 나와서 더 알아채기 어려운데요, 별칭에는 늘AS를 적고 열은 한 줄에 하나씩 쓰면 빠진 쉼표가 눈에 잘 띕니다. - 계산 열에 이름을 안 붙입니다: 문법 문서에 따르면
channel처럼 열 이름만 쓰면 그 이름이 그대로 별칭이 되지만,unit_price * quantity같은 계산식은 별칭이 없으면 이름 없는 열이 되어 쿼리 안에서 이름으로 부를 수 없습니다. 결과 화면에 임시 이름이 보이더라도 그 이름은 별칭처럼 쓸 수 없다고 문서는 적고 있죠. - 열 이름을 따옴표로 감쌉니다: BigQuery 에서 작은따옴표·큰따옴표는 문자열 값이고, 이름을 감싸는 것은 백틱입니다.
SELECT 'channel'은 channel 열이 아니라 「channel」이라는 글자를 행마다 돌려주는데요, 어휘 구조 문서에 따르면FROM처럼 예약어와 같은 이름이나 숫자로 시작하는 이름도 백틱으로 감싸야 합니다.
키워드와 열 이름은 대소문자를 구분하지 않아 select channel from shop.orders 도 돌아가지만, 같은 문서에 따르면 데이터셋·표 이름은 (따로 설정하지 않는 한) 대소문자를 구분합니다. 이 시리즈에서 키워드를 대문자로 쓰는 것은 읽기 쉽게 하려는 관례입니다.
마치며
SQL SELECT 문은 FROM 으로 표를 정하고 SELECT 로 열을 고르는 데서 시작하고, 여기에 AS 로 이름을 붙이고 DISTINCT 로 중복을 빼고 계산 열을 더하면 원본을 건드리지 않고 보고서 모양을 만들 수 있습니다. SELECT * 는 표를 처음 볼 때만 쓰고, 다시 쓸 쿼리에는 필요한 열을 직접 적어 두시길 권합니다.
저도 시리즈를 따라가며 공부하고 있으니 전체 커리큘럼을 참고해 주세요.
다음 글에서는 WHERE 로 조건에 맞는 행만 거르는 법을 다룹니다.
자주 묻는 질문
- SQL SELECT 문은 어떻게 쓰나요?
- SELECT 뒤에 보고 싶은 열 이름을 쉼표로 이어 적고, FROM 뒤에 표 이름을 적습니다. 예를 들어 SELECT order_id, channel FROM shop.orders; 는 주문 표에서 두 열만 꺼냅니다. 결과는 새 표로 돌아오고 원본 표는 바뀌지 않습니다.
- SELECT * 를 쓰면 안 되나요?
- 처음 보는 표의 모양을 확인할 때는 괜찮습니다. 다만 표에 열이 추가되거나 순서가 바뀌면 결과도 따라 바뀌고, 필요 없는 열까지 읽어 쿼리가 느려질 수 있어서 보고서처럼 다시 쓸 쿼리에는 열 이름을 직접 적는 편이 안전합니다. BigQuery 에서는 SELECT * 에 LIMIT 를 붙여도 읽는 데이터 양이 줄지 않습니다.
- SQL DISTINCT 는 어떤 기준으로 중복을 빼나요?
- SELECT 에 적은 열 전체의 조합이 같은 행을 중복으로 보고 한 줄만 남깁니다. SELECT DISTINCT channel 은 채널 종류만, SELECT DISTINCT channel, product 는 채널과 상품 조합의 종류를 돌려줍니다.
관련 글 더 보기
- SQL 이란? 명령어 종류와 쿼리가 실행되는 순서 - SQL 기초 시리즈 5회, FROM 부터 읽는 실행 순서
- 관계형 데이터베이스 구조: 테이블·행·열·스키마 - SQL 기초 시리즈 1회, 행과 열의 뜻
- 엑셀 중복 값 제거와 찾기 | 중복 제거·조건부 서식·UNIQUE 함수 - DISTINCT 와 닮은 엑셀 기능
