본문으로 건너뛰기

SELECT 문

SQLD 목차SQL 기본레슨 13 / 35

목차

SELECT 문은 테이블에서 원하는 열을 골라 결과 표를 만듭니다. 식으로 새 열을 만들고, 별칭으로 열 이름을 바꾸고, DISTINCT로 겹치는 행을 하나로 줄일 수 있습니다.

EMP에는 열이 다섯 개 있지만, "사원마다 연봉이 얼마인가?"에 답하는 데는 이름과 월급만 있으면 됩니다. 연봉처럼 테이블에 없는 값은 월급으로 계산해서 보여 줍니다. 보여 줄 열과 그 모양은 SELECT 절에, 가져올 테이블은 FROM 절에 적습니다.

7단계 중 1단계. SELECT *는 테이블의 모든 열을 가져옵니다.

1열 고르기와 산술 식

*는 테이블을 만들 때 정한 열 차례(EMPNO·ENAME·SAL·DEPTNO·MGR)대로 모든 열을 냅니다. 열 이름을 쉼표로 늘어놓으면 테이블의 차례가 아니라 적은 차례를 따릅니다. 식으로 만든 열의 머리에는 공백을 뺀 식이 대문자로 붙습니다(sal * 12 → SAL*12).

산술 연산은 *·/를 +·-보다 먼저 합니다. 100 + 20 * 3은 160이고, 먼저 더하려면 (100 + 20) * 3처럼 괄호로 묶습니다. NULL이 섞인 산술 연산은 결과도 NULL입니다. 모르는 값에 무엇을 해도 여전히 모르기 때문입니다.

2별칭과 연결 연산자

별칭은 결과 열에 붙이는 다른 이름이고, 앞의 AS는 빼도 됩니다. 큰따옴표 없이 쓴 별칭은 대문자로 바뀝니다. 공백·특수 문자를 넣거나 대소문자를 지키려면 큰따옴표로 감쌉니다. 큰따옴표 없이 AS Year Sal로 쓰면 ORA-00923 오류입니다. 큰따옴표는 열 이름·별칭에, 작은따옴표는 문자열 값에 씁니다. 그래서 WHERE ENAME = "김민준"은 "김민준"을 열 이름으로 읽어 ORA-00904(invalid identifier) 오류가 납니다. SELECT에서 붙인 별칭은 시험 기준으로 ORDER BY에서만 쓸 수 있습니다(SELECT 문이 실행되는 순서 레슨에서 자세히).

문자열을 잇는 연결 연산자(concatenation operator)는 DBMS마다 다르고, NULL을 이을 때도 다릅니다.

OracleSQL Server
연결 연산자||+(2025부터 ||도)
NULL을 이으면NULL을 건너뜀결과가 NULL(기본 설정)

3DISTINCT

DISTINCT는 SELECT 바로 뒤에 한 번만 쓰고, 열 하나가 아니라 SELECT에 적은 열 전체에 걸립니다. 아무것도 쓰지 않으면 겹친 행도 모두 내는 ALL입니다.

쿼리겹친다고 보는 행결과
DISTINCT DEPTNODEPTNO가 같은 행4행(NULL도 한 행)
DISTINCT DEPTNO, MGRDEPTNO와 MGR이 모두 같은 행5행

DISTINCT를 쓴 쿼리의 ORDER BY에는 SELECT에 적은 열만 쓸 수 있습니다. 겹친 행을 하나로 접고 나면 SELECT에 없는 EMPNO는 어느 행의 값인지 정할 수 없어서, ORDER BY EMPNO는 ORA-01791 오류입니다.

예제

테이블 없이 값만 계산할 때 Oracle은 DUAL을 씁니다. DUAL은 Oracle이 미리 만들어 둔 한 행짜리 테이블입니다.

SELECT 520 AS total,
  520 * 12 "Year Sal",
  '정하늘' || NULL AS JOINED,
  300 + NULL AS PLUS
FROM DUAL;
TOTALYear SalJOINEDPLUS
5206240정하늘NULL
  • 큰따옴표 없는 total은 TOTAL이 되고, "Year Sal"은 공백과 대소문자가 그대로 남습니다. AS가 없어도 별칭입니다.
  • Oracle의 ||는 NULL을 건너뛰어 '정하늘'만 남지만, 산술 연산은 NULL이 됩니다.
  • Oracle 23부터는 FROM DUAL을 빼도 됩니다. SQL Server는 FROM 없이 SELECT 1 + 1로 씁니다.

시험 포인트

  • 결과 열은 SELECT에 적은 차례대로 나오고, *는 테이블의 모든 열입니다.
  • AS는 빼도 됩니다. 별칭에 공백이 들면 큰따옴표가 있어야 합니다.
  • 문자열 값을 큰따옴표로 감싸면 열 이름으로 읽혀 오류가 납니다.
  • *·/가 +·-보다 먼저입니다. NULL이 섞인 산술은 NULL이고, 연결 연산자 가운데에서는 Oracle의 ||만 NULL을 건너뜁니다.
  • 시험 기준으로 연결은 Oracle이 ||, SQL Server가 +입니다.
  • DISTINCT는 SELECT에 적은 열 전체에 걸리고, NULL도 한 행으로 남깁니다. 그 쿼리의 ORDER BY에는 SELECT에 적은 열만 씁니다.

확인 문제

1. 다음 두 쿼리의 결과는 각각 몇 행일까요?

SELECT DISTINCT MGR
FROM EMP;
SELECT DISTINCT MGR, SAL
FROM EMP;
정답

4행과 6행입니다. MGR만 보면 1006과 1001이 두 번씩 나와 1001·1004·1006·NULL 넷으로 줄어듭니다. SAL까지 보면 여섯 사원의 월급이 모두 달라서 (MGR, SAL) 짝이 같은 행이 없습니다.

2. 다음 쿼리의 결과 열 이름 셋은 무엇일까요?

SELECT SAL * 12 AS yearSal,
  SAL * 12 "yearSal",
  SAL * 12
FROM EMP
WHERE EMPNO = 1001;
정답

YEARSAL · yearSal · SAL*12입니다.

YEARSALyearSalSAL*12
624062406240
  • 첫째: 따옴표 없는 yearSal이 모두 대문자가 됩니다.
  • 둘째: AS가 없어도 별칭이고, 큰따옴표 안의 소문자가 살아 있습니다.
  • 셋째: 별칭이 없으니 식이 공백 없이 열 머리가 됩니다.

3. 정하늘(1005)은 SAL이 300이고 DEPTNO가 NULL입니다. 다음 쿼리의 A·B·C는 무엇일까요?

SELECT SAL + 100 * 2 AS A,
  (SAL + 100) * 2 AS B,
  SAL + DEPTNO AS C
FROM EMP
WHERE EMPNO = 1005;
정답
ABC
500800NULL
  • A: 100 × 2를 먼저 해 300 + 200입니다.
  • B: 괄호 안 400을 먼저 구해 두 배입니다.
  • C: 부서 칸이 비어 있어 더한 값도 비어 있습니다.

끝까지 내려오면 저절로 표시됩니다. 이 기기에만 저장합니다.

SQLD 목차로