샘플 스키마 : HR
설명하는 과정에서 예제로 주어진 문장은 눈으로 보지만 말고 직접 실행시켜 보길 권한다.
문장의 구조를 표현할 때 기호의 의미
'|' = 또는(=OR)
'[]' = 생략 가능한 문장(생략하게 되면 자동으로 기본값)
SELECT 구문은 테이블로부터 행을 검색하는데 이용하는 RDB의 가장 기본적인 문장이다.
No. 01 |
|
| |
SELECT 문을 이용한 검색 |
기본 구조
SELECT * | {[DISTINCT] 컬럼명 or 표현식 [별명], …}
FROM 테이블명;
- '*'는 모든 컬럼을 검색할 때 사용한다.
- '*'는 컬럼명(or 표현식)과 같이 사용할 수 없고 반드시 단독으로 사용한다.
- SELECT 절과 FROM 절은 생략할 수 없다.
◈ 예제
select * from departments;
select department_name from departments;
예제 외에도 다른 테이블과 다른 컬럼을 검색해 보도록 한다.
테이블의 구조를 검색
DESCRIBE 테이블명; 또는 DESC 테이블명;
- 테이블의 구조(컬럼의 이름, 데이터 타입)을 확인할 수 있다.
◈ 예제
desc departments;
오라클이 지원하는 데이터 타입에 대해서는 나중에 설명하도록 하겠다.
모든 테이블 목록 검색
SELECT * FROM tab;
- 현재 스키마의 모든 테이블 목록을 검색한다.
TIP
SQL Developer의 왼쪽 창을 보면 테이블, 뷰 등 여러가지 메뉴가 있다.
테이블을 클랙해보면 현재 스키마의 모든 테이블 목록을 보여준다.
테이블 목록에서 원하는 테이블을 클릭해보면 테이블의 구조를 확인 가능하다.
SQL Developer를 사용하지 않는 상황이라면 위의 명령어들로 스키마의 구조를 파악하는 것이 중요!
별명을 사용한 검색
SELECT 컬럼명 as 별명, 컬럼명 as "별명", 컬럼명 별명, 컬럼명 "별명", …
FROM 테이블명;
- 별명은 결과를 출력할 때 컬럼의 이름을 별명으로 바꿔서 표현해준다.
- 'as'는 생략 가능하다.
- 위의 4가지 표현식 모두 사용 가능하다.
- "(이중인용부호)를 사용하지 않으면 대문자로 표현된다.
- "(이중인용부호)의 사용이 필요한 경우
- 대소문자를 구별하고 싶은 경우
- 특수 문자가 포함된 경우
- 공백이 포함된 경우
◈ 예제
select last_name as name, last_name as "Name", last_name Name, last_name "name"
from employees;
수식을 사용한 검색
SELECT 수식 [별명], …
FROM 테이블명;
- 수식을 사용할 경우에는 컬럼명에 수식이 출력되므로 별명을 사용하는 것을 권장한다.
- 수식을 사용할 때 컬럼에 NULL값이 존재할 경우 결과는 항상 NULL값이므로 주의한다.
◈ 예제
select last_name "Name", salary*12, salary*12 "Annual Salary"
from employees;
select last_name "Name", salary*12 + salary*12*commission_pct "annual Salary"
from employees;
commission_pct는 보너스 비율을 나타낸 값으로 보너스를 받지 않는 사람은 null 값이다.
모든 직원은 월급이 있지만 결과는 null로 나타나고, 보너스를 포함한 연봉이 얼마인지 알 수 없다.
salary에는 null값이 없지만 null값을 가진 commission_pct와 계산할 경우 null값으로 되는 것을 볼 수 있다.
◆ NULL(널 값) 이란?
널 값은 0이나 공백과는 다른 값으로, 아직 정해지지 않은 특별한 값을 의미한다.
널 값이 포함된 컬럼은 보통 연산을 사용하는 경우 정확한 결과를 볼 수 없기 때문에 주의한다.
널 값을 연산하기 위한 NVL 함수
NVL(컬럼명, 변환 값)
- 컬럼에 널 값이 있을 경우 변환 값으로 변환한다.
- 널 값이 아닌 경우 원래 값이 출력된다.
- 변환 값의 타입은 반드시 컬럼의 타입과 일치해야 한다.
◈ 예제
select last_name "Name", commission_pct, nvl(commission_pct, 0)
from employees;
널 값이 0으로 변환된 것을 볼 수 있다.
select last_name "Name", salary*12 + salary*12*nvl(commission_pct,0) "Annual Salary"
from employees;
이전의 보너스를 포함한 연봉을 검색하는 식을 nvl함수를 사용하여 검색하였다.
수식의 결과가 null 값이었던 것과는 달리 보너스를 포함한 연봉의 결과를 정확하게 볼 수 있다.
No. 02 |
|
| |
연결 연산자 |
기본 구조
SELECT 컬럼명 || '문자열' || …
FROM 테이블명;
- 연결 연산자(||)는 문자열이나 컬럼을 하나의 문자열로 검색한다.
- 숫자를 사용할 경우 단일 인용부호(')를 생략 가능하다.
- 연결 연산자(||)는 사칙연산 중 '+','-'보다 우선순위가 높다.
◈ 예제
▶ 컬럼끼리의 연결
select last_name || job_id "Employees"
from employees;
|
last_name 컬럼과 job_id의 컬럼이 하나의 문자열로 검색된다. |
▶ 컬럼과 문자열의 연결
select last_name || ' is a ' || job_id "Employees"
from employees;
|
문자열을 이용하여 보기 좋게 검색할 수 있다. |
select last_name || ' ' || salary+120
from employees;
ORA-01722: invalid number
01722. 00000 - "invalid number"
*Cause: The specified number was invalid.
*Action: Specify a valid number.
SQL문만 보면 맞는 문장 같지만 위와 같은 에러가 생긴다.
에러가 생긴 이유는 연결 연산자(||)가 +, -보다 우선순위가 높기 때문인데,
연결 연산자를 이용한 결과는 모두 문자로 취급되기 때문에 위의 SQL문은 문자+120이 된 것이다.
정상적으로 결과를 얻기 위해서는 괄호를 이용하여 (salary+120)을 계산하고 수행하면 된다.
select last_name || ' ' || (salary+120)
from employees;
원래의 월급보다 120이 많은 월급의 결과를 이름과 함께 하나의 문자열로 결과를 볼 수 있다.
단일 인용부호(')를 포함한 문자의 연결
SELECT 컬럼 || '''문자열''' || …
또는 SELECT 컬럼 || q' <'문자열'>' || …
- 나타내고 싶은 단일 인용부호(')옆에 단일 인용부호(')를 하나 더 추가하면 된다.
- 두번째, select 절의 <>대신 (),[],{} 다양한 괄호 사용이 가능하다.
select department_name || ', it''s good department' evaluation
from departments;
select department_name || q'<, it's good department>' evaluation
from departments;
두 개의 방법 모두 같은 결과를 볼 수 있다.
개인적으로 문장열이 복잡해 질수록 두 번째 방법이 더 사용하기 편할 것 같다.
No. 03 |
|
| |
중복 제거 |
기본 구조
SELECT [DISTINCT | ALL] 컬럼명, 컬럼명, …
FROM 테이블명;
- DISTINCT : 중복된 출력 값은 한번만 출력한다.
- ALL : 중복된 값을 모두 출력한다.
- DISTINCT 나 ALL 아무것도 쓰지 않으면 기본값은 ALL로 인식된다.
◈ 예제
▶ ALL
select department_id
from employees;
|
중복된 모든 정보를 출력한다. |
▶ DISTINCT
select distinct department_id
from employees;
|
중복된 결과를 한번만 출력한다. |
TIP DISTINCT의 잘못된 예
select distinct department_id, last_name
from employees;
위의 예는 DISTINCT를 잘못 사용한 경우이다.
중복을 제거할 경우에는 레코드 단위로 중복을 검사하기 때문에 department_id와 last_name이 둘다 같은 행이 있어야 중복으로 처리된다.
last_name이 같은 경우가 없다면 결국, ALL을 한 경우와 같다. 필요없는 작업을 한 것이다.
지금같이 데이터의 수가 적은 경우에는 문제없지만 대용량의 데이터가 쌓여있는 데이터베이스에서 DISTINCT를 사용한다면 오라클의 성능을 떨어뜨릴 가능성이 있다. 즉, 결과의 출력이 늦을 수 있다. 그러므로 결과를 조금 더 빠르게 보기 위해서는 필요한 경우를 제외하고 DISTINCT를 사용하지 말자!
'SQL' 카테고리의 다른 글
[SQL 05] ORDER BY 절 (0) | 2017.12.03 |
---|---|
[SQL 04] WHERE 절 (0) | 2017.12.03 |
[SQL 02] SQL Developer 간단 사용법 & SQL 언어 (0) | 2017.11.29 |
[SQL 01] HR schema 구조 (0) | 2017.11.29 |
[SQL 00] SQL실습을 위한 Oracle XE 11g 설치 및 준비 (0) | 2017.11.29 |