- 이 글은 도서 '초보자를 위한 SQL 200제'라는 책을 바탕으로 작성되었습니다.
- 들어가기에 앞서 SQL의 종류에 대한 글을 선행하고 오시는 걸 추천드립니다
005. 중복된 데이터를 제거해서 출력하기 - DISTINCT
같은 내용이 반복될 때 중복된 데이터를 제거하고 출력하려면 'DISTINCT' 키워드 또는 'UNIQUE' 키워드를 이용하면 됩니다. 컬럼명 앞에 DISTINCT 또는 UNIQUE를 작성하고 실행하면 중복행이 제거되고 UNIQUE 한 값만 출력됩니다
SELECT DISTINCT(또는 UNIQUE) 컬럼1
FROM 테이블 명;
Q. 사원 테이블에서 직업을 출력하는데 중복된 데이터를 제외하고 출력하라
SELECT DISTINCT JOB
FROM EMP;
SELECT UNIQUE JOB
FROM EMP;
006. 데이터를 정렬해서 출력하기 - ORDER BY
데이터를 정렬해서 출력하려면 ORDER BY절을 사용하면 됩니다. ORDER BY 절 다음에 정렬하고자 하는 데이터의 컬럼명을 기술하고, 정렬 방식(오름차순, 내림차순)에 대한 옵션을 컬럼명 다음에 작성합니다
* 컬럼명 옆에 정렬 옵션을 지정하지 않으면 기본값으로 오름차순으로 정렬합니다 (default = ASC)
정렬 방식 | 정렬 옵션 | 축약 |
오름차순 | ASCENDING | ASC |
내림차순 | DESCENDING | DESC |
-- 오름차순
SELECT 컬럼1, 컬럼2
FROM 테이블명
ORDER BY 컬럼1 ASC(또는 ASCENDING);
-- 내림차순
SELECT 컬럼1, 컬럼2
FROM 테이블명
ORDER BY 컬럼1 DESC(또는 DESCENDING)
컬럼별칭 사용 가능
ORDER BY 절은 SQL 작성 시 가장 마지막에 작성하며 오라클이 실행할 때도 가장 마지막에 실행합니다. 때문에 SELECT절에서 사용한 컬럼별칭을 ORDER BY절에서 사용할 수 있습니다.
SELECT ENAME, SAL*(1+0.5) AS 보너스
FROM EMP
ORDER BY 보너스 ASC;
정렬 기준 2개 이상 선택 가능
ORDER BY절에는 다음과 같이 컬럼을 여러 개 작성할 수 있습니다.
SELECT ENAME, DEPTNO, SAL
FROM EMP
ORDER BY DEPTNO ASC, SAL DESC;
위 SQL ORDER BY절에서 가장먼저 부서 번호(DEPTNO)를 오름차순으로, 월급(SAL)을 내림차순으로 정의하고 있다. 따라서 결과는 다음과 같이 부서 번호를 먼저 오름차순으로 정렬하고, 부서 번호를 오름차순으로 정렬된 것을 기준으로 월급을 내림차순으로 정렬하고 있다.
컬럼명 대신 번호 사용 가능
ORDER BY절에 컬럼명 대신 숫자를 적어줄 수도 있다. 여기서 사용하는 숫자는 SELECT절 컬럼의 순서이다.
SELECT ENAME, DEPTNO, SAL
FROM EMP
ORDER BY 2 ASC, 3 DESC;
Q. 이름과 월급을 출력하는데 월급이 낮은 사원부터 출력하라
SELCT ENAME, SAL
FROM EMP
ORDER BY SAL ASC;
007. WHERE절 배우기 (숫자 데이터 검색)
WHERE 절은 검색하기 원하는 조건을 작성하여 데이터를 검색한다. WHERE절의 검색 조건으로 사용하는 비교 연산자는 다음과 같다.
1) 비교연산자
연산자 | 의미 |
> | 크다 |
< | 작다 |
>= | 크거나 같다 |
<= | 작거나 같다 |
= | 같다 |
!= , ^= , <> | 같지않다 |
2) 기타 비교 연산자
연산자 | 의미 |
BETWEEN AND | ~사이에 있는 |
LIKE | 일치하는 문자패턴 검색 |
IS NULL | NULL 여부 |
IN | 값 리스트 중 일치하는 값 검색 |
N O T E 별칭을 쓸 때 주의할 점
-- 부적합한 식별자오류
SELECT ENAME, JOB, SAL AS '월급'
FROM EMP
WHERE 월급 = 3000;
SQL이 작성되는 순서는 SELECT - FROM - WHERE 순이지만 실제로 실행되는 순서는 FROM - WHERE - SELECT로, 오라클은 FROM 절을 실행하고 나서 WHERE 절을 실행하기 때문에 WHERE절에서 별칭을 쓸 경우 에러가 발생합니다. FROM 절을 실행하면서 데이터베이스에서 EMP테이블을 가져오고 WHERE을 실행하면서 EMP테이블에서 한글로 된 '월급'컬럼을 찾아보지만 없기 때문에 부적합한 식별자라고 수행되며 오류가 발생합니다.
Q. 월급이 3000인 사원들의 이름, 월급, 직업을 출력하라
SELECT ENAME, SAL, JOB
FROM EMP
WHERE SAL > 3000;
008. WHERE절 배우기 (문자와 날짜 검색)
WHERE절에서 문자와 날짜에 대한 조건을 제시할 경우 숫자와 다르게 따옴표('')로 감싸 주어야 합니다. 이는 따옴표 안에 있는 것이 숫자가 아닌 문자임을 오라클에게 알려주는 것입니다.
날짜 데이터 검색의 경우 현재 접속한 세션의 날짜 형식에 맞춰 작성해주어야 합니다. 예를 들어 '81/11/17'의 경우 연도/월/일로 된 날짜 형식입니다. 그러나 우리나라와는 다르게 미국이나 영국의 날짜 형식은 '일/월/연도' 형식이므로 '17/11/81'로 검색해야 합니다. 나라마다 날짜 형식이 다르기 때문에 날짜 검색을 하기 전에 현재 접속한 세션의 날짜 형식을 확인하는 것이 필요합니다.
현재 접속한 세션의 날짜 형식은 NSL_SESSION_PARAMETERS를 조회하여 확인합니다.
SELECT *
FROM NLS_SESSION_PARAMETERS
WHERE PARAMETER = 'NLS_DATE_FORMAT';
날짜 형식에 대한 정의는 다음과 같습니다.
정의 | 형식 | 정의 | 형식 |
YYYY | 연도 4자리 | HH24 | 시간(0~24) |
YY 또는 RR | 연도 2자리 | MI | 분(0~59) |
MM | 달의 2자리 값 | SS | 초(0~59) |
MON | 달의 영문 약어 | WW | 연의 주 |
DD | 숫자 형식의 일 | IW | ISO 표준에 따른 년의 주 |
DAY | 요일 | W | 월의 주 |
DY | 요일 약어 | YEAR | 영어 철자로 표기된 년도 |
D | 요일의 숫자 | MONTH | 영어 철자로 표기된 달 |
YY와 RR의 차이
여기서 YY와 RR은 서로 다릅니다. 그 이유를 알기 위해 예를 들어보면 81년도를 YY로 검색할 경우, YY는 81년을 2081년으로 인식하고 검색합니다. 즉 YY는 81년도를 현재 세기의 연도로 인식하기 때문에 2081년을 검색합니다.
하지만 81년을 RR로 검색할 경우 현재 세기를 기준으로 이전 세기로 인식하기 때문에 81년을 1981년으로 인식하고 검색합니다. 따라서 RR/MM/DD 형태일 때와 YY/MM/DD일 때의 검색은 완전히 다른 시기를 검색하는 것과 같습니다.
Q. 이름이 SCOTT인 사원의 이름, 월급, 직업, 입사일, 부서 번호를 출력하라
SELECT ENAME, SAL, JOB, HIREDATE, DEPTNO
FROM EMP
WHERE ENAME = 'SCOTT';
Q. 81년 11월 17일에 입사한 사원의 이름, 월급, 직업, 입사일을 출력하라
SELECT ENAME, SAL, JOB, HIREDATE
FROM EMP
WHERE HIREDATE = '81/11/17';
009. 산술 연산자 배우기 - * / + -
산술 연산자의 경우 일반적인 계산과 같이 우선순위가 있기 때문에 곱하기와 더하기가 같은 식에 있으면 곱하기부터 실행합니다. 만약 더하기부터 실행하고 싶다면 괄호를 사용하면 됩니다.
곱하기부터 실행 | 더하기부터 실행 | |
SQL | SELECT 300+200*2 FROM DUAL; | SELECT (300+200)*2 FROM DUAL; |
결과 | 700 | 1000 |
N O T E NULL
다음의 쿼리는 부서 번호가 10번인 사원들의 이름, 월급, 커미션, 월급 + 커미션을 출력하는 SQL입니다.
SELECT ENAME, SAL, COMM, SAL + COMM
FROM EMP
WHERE DEPTNO = 10;
부서 번호가 10번인 사람들은 커미션에 데이터가 없는데, 이와 같은 상태를 NULL값이라 합니다. NULL은 데이터가 없는 상태, 즉 데이터가 할당되지 않은 상태 또는 알 수 없는 값이라고 합니다. 그래서 커미션이 NULL인 사원들은 월급+커미션의 결과도 NULL이 됩니다.
산술식의 컬럼 값이 NULL인 경우 결과도 NULL이기 때문에 이 경우 NULL이 아닌 숫자로 변경해주어야 월급+커미션 값이 출력될 수 있습니다.
SELECT ENAME, SAL, COMM, SAL+NVL(COMM,0) --NVL함수를 사용합니다
FROM EMP
WHERE DEPTNO = 10;
NVL함수는 NULL 데이터를 처리하는 함수입니다. NVL(COMM,0)은 COMM을 출력할 때 COMM이 NULL이면 0으로 출력하는 함수입니다. 따라서 이전에 NVL함수를 사용하지 않았을 때 NULL값이 나왔던 것과 달리 NVL함수를 사용함으로 인해 숫자가 출력되는것을 확인할 수 있습니다.
Q. 연봉이 3600 이상인 사원들의 이름과 연봉을 출력하라
WHERE절에서는 SELECT에서 정의한 별칭을 사용할 수 없기 때문에 연봉 계산을 위해 WHERE절에는 SAL * 12 >=3600을 조건으로 두어야 합니다. * 007번 참고
SELECT ENAME, SAL*12 AS 연봉
FROM EMP
WHERE SAL * 12 >= 3600;