
현재 Oracle을 학습하고 있고, 이에 따라 Oracle 기본 문법들을 정리해볼까 합니다.
기본적으로 SQL 자체는 보면 직관적이라 이해는 편한데 문제는 외울 것이 많고 SQL이 아닌 다른 언어들(C든, Java든 ...)과 다른 면이 존재해 문법이 생각 안날 때가 있어 간단하게 정리하고자 이 시리즈를 시작하게 되었습니다.
기본적인 DB(Database)에서의 Table 구조는 아래와 같습니다(이미지 출처).

SQL의 정의는 아래와 같습니다.
DBMS에서 데이터를 조회 및 조작하기 위해 사용하는 표준 검색 언어
그리고 이를 용도에 맞게 분류하면 아래와 같습니다.
| 분류 | 용도 | 명령어 |
|---|---|---|
| DQL(Data Query Language) | 데이터 검색 | SELECT |
| DML(Data Manipulation Language) | 데이터 조작 | INSERT, UPDATE, DELETE |
| DDL(Data Definition Language) | 데이터 정의 | CREATE, DROP, ALTER |
| TCL(Transaction Control Language) | 트랜젝션 제어 | COMMIT, ROLLBACK |
한 줄 주석은 -- 여러 줄 또는 범위 주석은 /**/ 로 작성합니다.
-- 한 줄 주석
/*
여러 줄
주석
*/
데이터를 조회한 결과를 Result Set이라고 하는데, 조회를 위해 사용하는 것이 바로 SELECT구문입니다. 기본적으로 아래와 같은 문법을 사용합니다.
SELECT 칼럼 명 [, 컬럼 명, ...]
FROM 테이블 명
WHERE 조건식;
간단한 활용법을 시작하기 전 EMPLOYEE 테이블의 칼럼명은 다음과 같습니다.
EMP_ID : 사원번호(primary key)EMP_NAME : 직원명EMP_NO : 주민등록번호EMAIL : 이메일PHONE : 전화번호DEPT_CODE : 부서코드JOB_CODE : 직급코드SALARY : 급여BONUS : 보너스율MANAGER_ID : 관리자사번HIRE_DATE : 입사일ENT_DATE : 퇴사일ENT_YN : 퇴직여부직원 전부의 사번과 이름, 월급을 조회하는 구문입니다. 필요한 칼럼 명을 모두 적으면 됩니다.
SELECT EMP_ID, EMP_NAME, SALARY
FROM EMPLOYEE;
칼럼 전체 조회를 하려면 칼럼 명 전부 입력해도 되지만, *를 이용하면 좀 더 편합니다.
SELECT *
FROM EMPLOYEE;
산술 연산도 가능합니다. 이름, 연봉, 보너스 포함 연봉을 계산해봅니다.
SELECT EMP_NAME, SALARY * 12, (SALARY + (SALARY * BONUS)) * 12
FROM EMPLOYEE;
이 때, 윗 쿼리를 그대로 입력하면 컬럼 명이 SALARY * 12, (SALARY + (SALARY * BONUS)) * 12 와 같이 그대로 나옵니다. 이를 다른 이름으로 보이게 할 수 있는데, AS를 사용합니다.
SELECT EMP_NAME AS "이름",
SALARY * 12 AS "연봉(원)",
(SALARY + (SALARY * BONUS)) * 12 AS "총 소득(원)"
FROM EMPLOYEE;
참고로 AS를 생략해도 무방하나, 콤마의 유무를 자세히 보는 등 쿼리문에서 식별하기 조금 어려울 수 있기에 AS를 쓰는 것을 추천합니다.
임의로 지정한 문자열을 SELECT문에서 사용 가능합니다. 예를 들어 SALARY 뒤에 칼럼을 하나 추가하여 원을 보고 싶으면 아래와 같이 작성하면 단위 컬럼이 새로 보이면서 원으로 전부 채웁니다.
SELECT EMP_ID
SALARY
'원' AS "단위"
FROM EMPLOYEE;
중복을 제거할 때는 DISTINCT를 사용합니다. 예를 들어 직급코드는 여러 사람이 동일한 직급일 수 있으므로 이를 제거하려면 다음과 같이 작성합니다.
SELECT DISTINCT JOB_CODE
FROM EMPLOYEE;
조회하고자 하는 테이블로부터 특정 조건에 만족하는 데이터만을 조회할 때 사용합니다. 조건식에서도 다양한 연산자 사용이 가능한데 이는 아래와 같습니다.
기본적으로 다른 언어와 비슷합니다. 다만 비교 연산자에서 동등을 나타내는 것이 다른 언어와는 다르게 ==이 아닌 =입니다.
AND : 그리고OR : 또는NOT : 반대로 반환>, <, >=, <= : 대소비교= : 양쪽이 같다!=, ^=, <> : 양쪽이 다르다BETWEEN 작은 값 AND 큰 값 : 특정 범위 포함 여부 확인, 순서 주의!LIKE / NOT LIKE : 문자 패턴 비교IS NULL / IS NOT NULL : NULL 여부IN / NOT IN : 비교 값 목록에 포함 / 미포함다른 부분들은 다른 언어와 거의 비슷한 측면이 있습니다. 다만 SQL에서 다른언어에서는 다루지 않는 조금은 특별한 부분만 다루도록 하겠습니다.
급여를 350만원보다 많이 받고 600만원보다 적게 받는 직원 이름과 급여 조회
SELECT EMP_NAME, SALARY
FROM EMPLOYEE
WHERE SALARY >= 3500000 AND SALARY <= 6000000;
또는
SELECT EMP_NAME, SALARY
FROM EMPLOYEE
WHERE SALARY BETWEEN 3500000 AND 6000000;
비교하려는 값이 특정 패턴을 만족하는지 여부를 봅니다. 이 때 %와 _ 를 사용하는데, 이를 와일드카드라 합니다.
이% : '이'로 시작하는 패턴 다 포함, %는 길이에 관계 없이 비교합니다.이__ : '이'로 시작하며 뒤에 두 글자만 있는 패턴만 포함, _는 작성한 갯수만큼 길이가 제한되어 있습니다.그러면 만약에 이메일을 조회하려는데 _ 앞에 3글자만 있는 것들만 조회하려면 WHERE 절은...?
...
WHERE EMAIL LIKE '____%'
그런데 이렇게 적으면 뭐가 와일드카드인지, 뭐가 그냥 문자인지 알 수가 없습니다. 이를 해결하기 위해 ESCAPE OPTION이 필요하고 다음과 같이 적으면 됩니다.
...
WHERE EMAIL LIKE '___/_%' ESCAPE '/'
ESCAPE OPTION은 다른 문자도 가능합니다. EMAIL LIKE '___#_%' ESCAPE '#' 역시 동일합니다. 즉, ESCAPE OPTION을 만나는 순간, 와일드카드 _가 이어진 것을 한번 끊어주는 역할을 하는 것을 알 수 있습니다.
NULL, 즉 데이터가 없는지를 보고 있습니다. 간단하게 예시만 살펴보면, 만약 관리자도 없고 부서 배치도 받지 않은 직원은 다음과 같이 조회합니다.
SELECT EMP_NAME, MANAGER_ID, DEPT_CODE
FROM EMPLOYEE
WHERE MANAGER_ID IS NULL AND DEPT_CODE IS NULL;
OR 적는 것 대신 사용이 가능합니다. 간단하게 D6 부서와 D8 부서원들의 이름, 부서코드를 조회해보겠습니다. 우선 아래와 같이 적을 수 있습니다.
SELECT EMP_NAME, DEPT_CODE
FROM EMPLOYEE
WHERE DEPT_CODE = 'D6' OR DEPT_CODE = 'D8';
그리고 IN을 사용하면 위 쿼리를 더 간단하게 작성이 가능합니다.
SELECT EMP_NAME, DEPT_CODE
FROM EMPLOYEE
WHERE DEPT_CODE = IN('D6', 'D8');
이름에서 알 수 있듯 정렬 기준이 될 컬럼을 지정하는 절입니다. SELECT문의 가장 마지막에 작성하며, 실행 순서 역시 가장 마지막이 되는 부분입니다. 따라서 지금까지 포스팅한 표현법을 정리해보면 다음과 같습니다.
SELECT 칼럼1, 칼럼2, ...
FROM 테이블
WHERE 조건식
ORDER BY 정렬기준컬럼 | 별칭 | 컬럼순번 [ASC | DESC] [NULLS FIRST | NULLS LAST]
오름차순과 내림차순으로 구성되어 있습니다. ASC가 오름차순, DESC가 내림차순이고, 아무것도 안써주면 기본값은 ASC(오름차순)입니다.
그리고 정렬기준에 컬럼 값이 동일한 경우 그 다음 차순을 위해 여러 개를 제시할 수 있습니다, 예를 들어 전사원을 모든 정보를 조사하되, 보너스 기준으로 내림차순 먼저, 동일할 경우 급여로 오름차순한 것을 보여주는 쿼리는 아래와 같습니다.
SELECT *
FROM EMPLOYEE
ORDER BY BONUS DESC, SALARY ASC;
그런데 데이터 중에서 NULL이 있으면 정렬이 힘듭니다. 특히 자바라면... NullPointerException이 뜰 것입니다. 하지만 여기는 놀랍게도 정렬이 됩니다!
바로 NULL을 가장 작은 값 아니면 가장 큰 값으로 생각해서 정렬하는 것입니다. 여기서 기본값은 NULL이 가장 큰 값으로 설정이 되어 있다고 생각하면 편합니다.
가장 큰 값으로 생각하면 내림차순이면 맨 앞, 오름차순이면 맨 뒤에 있게 됩니다.
여기서 내림차순이든 올림차순이든 NULL의 위치를 고정할 수 있는 것이 있습니다. 그게 바로 NULLS FIRST(NULL을 맨 앞으로), NULLS LAST(NULL을 맨 뒤로) 입니다.
기본적으로 아래와 같이 작성하면 오름차순이므로 NULL이 맨 뒤로 가게 됩니다.
SELECT *
FROM EMPLOYEE
ORDER BY BONUS ASC;
이를 맨 앞으로 보내주려면 아래와 같이 작성합니다.
SELECT *
FROM EMPLOYEE
ORDER BY BONUS ASC NULLS FIRST;