[Oracle] SELECT 구문

주재완·2024년 2월 17일
0

[Old] Oracle

목록 보기
1/10
post-thumbnail

시작하기에 앞서...

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

Table 구조

기본적인 DB(Database)에서의 Table 구조는 아래와 같습니다(이미지 출처).

  • 열(Column, 컬럼)은 관련 데이터의 속성이고 유일한 이름을 가지고 있습니다. 또한 도메인(domain), 필드(field), 속성(attribute) 라고도 합니다.
  • 행(Row)은 관련 데이터들의 묶음을 나타내며 튜플(tuple) 또는 레코드(record)라고도 불립니다.
  • 테이블에서는 기본적으로 행을 찾기 위해 기본적으로 기준이 되는 컬럼이 존재합니다. 이를 기본키(Primary Key) 라고 하며 테이블 당 단 하나만(유일성) 존재합니다.
  • MySQL, Oracle과 같은 관계형 데이터베이스(RDBMS)의 경우, 다른 테이블로 연결하기 위한 식별자가 존재합니다. 다른 테이블에 연결하기 위한 연결자 역할을 하는 것을 외래키(Foreign Key) 라고 하며 이는 한 테이블에 여러 개 존재 가능합니다.

SQL(Structured Query Language)

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

주석

한 줄 주석은 -- 여러 줄 또는 범위 주석은 /**/ 로 작성합니다.

-- 한 줄 주석

/*
	여러 줄
    주석
*/

SELECT

데이터를 조회한 결과를 Result Set이라고 하는데, 조회를 위해 사용하는 것이 바로 SELECT구문입니다. 기본적으로 아래와 같은 문법을 사용합니다.

SELECT 칼럼 명 [, 컬럼 명, ...]
FROM 테이블 명
WHERE 조건식;

EMPLOYEE 테이블 컬럼명

간단한 활용법을 시작하기 전 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 예시

기본

직원 전부의 사번과 이름, 월급을 조회하는 구문입니다. 필요한 칼럼 명을 모두 적으면 됩니다.

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

중복을 제거할 때는 DISTINCT를 사용합니다. 예를 들어 직급코드는 여러 사람이 동일한 직급일 수 있으므로 이를 제거하려면 다음과 같이 작성합니다.

SELECT DISTINCT JOB_CODE
FROM EMPLOYEE;

WHERE

조회하고자 하는 테이블로부터 특정 조건에 만족하는 데이터만을 조회할 때 사용합니다. 조건식에서도 다양한 연산자 사용이 가능한데 이는 아래와 같습니다.

연산자

기본적으로 다른 언어와 비슷합니다. 다만 비교 연산자에서 동등을 나타내는 것이 다른 언어와는 다르게 ==이 아닌 =입니다.

논리 연산자

  • AND : 그리고
  • OR : 또는
  • NOT : 반대로 반환

비교 연산자

  • >, <, >=, <= : 대소비교
  • = : 양쪽이 같다
  • !=, ^=, <> : 양쪽이 다르다
  • BETWEEN 작은 값 AND 큰 값 : 특정 범위 포함 여부 확인, 순서 주의!
  • LIKE / NOT LIKE : 문자 패턴 비교
  • IS NULL / IS NOT NULL : NULL 여부
  • IN / NOT IN : 비교 값 목록에 포함 / 미포함

WHERE 예시

다른 부분들은 다른 언어와 거의 비슷한 측면이 있습니다. 다만 SQL에서 다른언어에서는 다루지 않는 조금은 특별한 부분만 다루도록 하겠습니다.

BETWEEN AND

급여를 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;

LIKE

비교하려는 값이 특정 패턴을 만족하는지 여부를 봅니다. 이 때 %_ 를 사용하는데, 이를 와일드카드라 합니다.

  • 이% : '이'로 시작하는 패턴 다 포함, %는 길이에 관계 없이 비교합니다.
  • 이__ : '이'로 시작하며 뒤에 두 글자만 있는 패턴만 포함, _는 작성한 갯수만큼 길이가 제한되어 있습니다.

그러면 만약에 이메일을 조회하려는데 _ 앞에 3글자만 있는 것들만 조회하려면 WHERE 절은...?

...
WHERE EMAIL LIKE '____%'

그런데 이렇게 적으면 뭐가 와일드카드인지, 뭐가 그냥 문자인지 알 수가 없습니다. 이를 해결하기 위해 ESCAPE OPTION이 필요하고 다음과 같이 적으면 됩니다.

...
WHERE EMAIL LIKE '___/_%' ESCAPE '/'

ESCAPE OPTION은 다른 문자도 가능합니다. EMAIL LIKE '___#_%' ESCAPE '#' 역시 동일합니다. 즉, ESCAPE OPTION을 만나는 순간, 와일드카드 _가 이어진 것을 한번 끊어주는 역할을 하는 것을 알 수 있습니다.

IS NULL

NULL, 즉 데이터가 없는지를 보고 있습니다. 간단하게 예시만 살펴보면, 만약 관리자도 없고 부서 배치도 받지 않은 직원은 다음과 같이 조회합니다.

SELECT EMP_NAME, MANAGER_ID, DEPT_CODE
FROM EMPLOYEE
WHERE MANAGER_ID IS NULL AND DEPT_CODE IS NULL;

IN

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');

ORDER BY

이름에서 알 수 있듯 정렬 기준이 될 컬럼을 지정하는 절입니다. SELECT문의 가장 마지막에 작성하며, 실행 순서 역시 가장 마지막이 되는 부분입니다. 따라서 지금까지 포스팅한 표현법을 정리해보면 다음과 같습니다.

SELECT 칼럼1, 칼럼2, ...
FROM 테이블
WHERE 조건식
ORDER BY 정렬기준컬럼 | 별칭 | 컬럼순번 [ASC | DESC] [NULLS FIRST | NULLS LAST]

ASC | DESC

오름차순과 내림차순으로 구성되어 있습니다. ASC가 오름차순, DESC가 내림차순이고, 아무것도 안써주면 기본값은 ASC(오름차순)입니다.

그리고 정렬기준에 컬럼 값이 동일한 경우 그 다음 차순을 위해 여러 개를 제시할 수 있습니다, 예를 들어 전사원을 모든 정보를 조사하되, 보너스 기준으로 내림차순 먼저, 동일할 경우 급여로 오름차순한 것을 보여주는 쿼리는 아래와 같습니다.

SELECT *
FROM EMPLOYEE
ORDER BY BONUS DESC, SALARY ASC;

NULLS FIRST | NULLS LAST

그런데 데이터 중에서 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;

참고

profile
안녕하세요! 언제나 탐구하고 공부하는 개발자, 주재완입니다.

0개의 댓글