[데이터베이스] Oracle SELECT

허경두·2025년 5월 16일

Database

목록 보기
4/9

SELECT

테이블 데이터를 조회할 때 사용하는 명령어

SELECT (DISTINCT) column_name (ALIAS)
FROM table_name;
  • SELECT * 로 모든 컬럼을 조회할 수 있다

  • SELECT salary * 100 과 같이 산술식을 넣어 출력할 수 있다

  • SELECT name || ' ' || title 과 같이 다른 컬럼이나 값을 연결해서 하나의 컬럼으로 출력할 수 있다

  • 쿼리 실행 순서
    FROMWHEREGROUP BYHAVINGSELECTORDER BY

ORDER BY

데이터 정렬 시 사용하는 명령어

SELECT (DISTINCT) column_name (ALIAS)
FROM table_name
ORDER BY [column_name | expression] [ASC | DESC];
  • ASC : 오름차순 정렬
  • DESC : 내림차순 정렬

WHERE

조건에 맞는 행을 선택하여 조회할 때 사용하는 명령어

SELECT (DISTINCT) column_name (ALIAS)
FROM table_name
WHERE [column_name | expression] [operator] [value]
  • Java Stream의 filter() 함수와 유사

WHERE절에 사용되는 연산자

논리 연산자

연산자의미예시
AND그리고salary > 3000 AND dept_id = 10
OR또는job_id = 'MANAGER' OR job_id = 'CLERK'
NOT부정NOT (salary < 5000)

논리 비교 연산자

연산자의미예시
=같다dept_id = 10
!= 또는 <>같지 않다salary != 5000
>크다age > 30
<작다score < 70
>=크거나 같다salary >= 3000
<=작거나 같다hire_date <= SYSDATE

SQL 비교 연산자

연산자 / 키워드의미예시
BETWEEN ... AND ...범위 내 포함 (양 끝 포함)score BETWEEN 70 AND 90
IN (...)지정한 목록 중 하나와 일치dept_id IN (10, 20, 30)
LIKE패턴(문자열) 일치 여부 검사name LIKE 'J%'
IS NULLNULL 여부 비교phone IS NULL
EXISTS (서브쿼리)서브쿼리 결과가 존재할 경우 TRUEWHERE EXISTS (SELECT 1 FROM emp WHERE dept_id = 10)
ANY (서브쿼리)서브쿼리 결과 중 하나라도 만족하면 TRUEsalary > ANY (SELECT salary FROM emp WHERE dept_id = 10)
ALL (서브쿼리)서브쿼리 결과 모두를 만족해야 TRUEsalary > ALL (SELECT salary FROM emp WHERE dept_id = 10)

NOT IN은 NULL 값이 있을 경우 FALSE가 되므로 NOT EXISTS 로 대체할 수 있다

GROUP BY

FROMWHERE 에 대한 결과 집합에 대해 grouping
2차원인 table을 grouping 하면 1차원인 row로 표현 가능

SELECT dept_id, region_id, AVG(salary)
FROM s_dept
GROUP BY dept_id, region_id
HAVING AVG(salary) > 2000
  • SELECT 에 그룹 함수가 오면 나머지 컬럼들은 GROUP BY 절에 기술되어야 한다
    → 위 예시에서 GROUP BYdept_id, region_id 둘 중 어느 하나도 빠지면 안된다
  • 그룹에 대한 조건은 WHERE 가 아닌 HAVING 에 기술해야 한다
  • 위 예시에서 dept_id 가 메인 그룹 region_id 가 서브그룹이다
    → 부서별 지역별 평균 급여

JOIN

하나 이상의 테이블로부터 연관된 데이터를 매핑하여 하나의 테이블처럼 만든다

JOIN 종류

EquiJoin

등치 조건
일반적으로 PK, FK 관계에 의해 JOIN이 성립한다

SELECT *
FROM table1, table2
WHERE table1.column1 = table2.column2;

Non-EquiJoin

= 연산자 외의 다른 연산자를 사용하여 JOIN하는 방법

SELECT *
FROM table1, table2
WHERE table1.column1 BETWEEN table2.column2 AND table2.column3;

column2column3 사이에 있는 column1 값들이 table2 의 row에 매핑된다

Outer Join

(+) 연산자가 있는 쪽에 데이터가 없으면 NULL로 표시된다

SELECT *
FROM table1, table2
WHERE table1.column1 (+) = table2.column2;
  • IN, OR 는 사용 불가
  • JOIN할 데이터가 부족한 쪽에 (+) 연산자를 위치시킨다
  • 둘 중 한 쪽에만 사용 가능하다

Self Join

하나의 테이블을 여러 개인 것처럼 사용 가능

SELECT *
FROM s_emp e1, s_emp e2
WHERE e1.manager_id = e2.id;
  • 위 예시는 직원 테이블에서 자신의 상사가 누군지 표시할 수 있다
  • 동적 계층 관계 표현

집합 연산자

두 개의 쿼리 결과에 대해 집합 연산을 수행한다

  • 컬럼들의 개수와 타입이 일치해야 한다
  • 첫 번째 쿼리의 컬럼명이 출력된다
  • ORDER BY 는 마지막에 한 번만 기술한다
  • UNION ALL 을 제외한 연산자는 교집합을 찾아야 하므로 성능이 떨어진다

집합 연산자 종류

  • UNION : 합집합
  • UNION ALL : 합집합인데 교집합을 제외하지 않는다
  • INTERSECT : 교집합
  • MINUS : 첫번째 결과 - 두번째 결과 (차집합)

Subquery

SELECT 문 안에 포함된 또 다른 SELECT

  • 서브쿼리는 ORDER BY 를 포함하지 않는다
  • 서브쿼리는 연산자 오른쪽에 나타나야 한다
  • 서브쿼리에 대해 사용 가능한 연산자
    • 단일행 연산자 : =, >, >=, <, <=, <>
    • 복수행 연산자 : IN, NOT IN
  • SELECT 외에도 CREATE, INSERT, UPDATE, DELETE 에서 사용 가능하다

서브쿼리 종류

scalar subquery 외에는 SELECT 에서 사용이 불가하다

Single Row Subquery (Scalar Subquery)

결과 행과 열이 하나인 서브쿼리. 즉, 단 하나의 데이터를 조회하는 쿼리
단일행 연산자를 사용한다

SELECT *
FROM s_emp
WHERE dept_id = ( SELECT dept_id FROM s_emp WHERE name = '김정미' );

Multi Row Subquery

결과 행은 여러개, 열은 하나인 서브쿼리
복수행 연산자를 사용한다

SELECT *
FROM s_emp
WHERE dept_id IN ( SELECT id FROM s_dept WHERE region_id = 3 );

Multi Column Subquery (Vector Subquery)

결과 행과 열이 여러 개인 서브 쿼리
복수행 연산자를 사용한다
pair-wise : 두 항목씩 짝지어 비교하거나 계산

SELECT *
FROM s_emp
WHERE (salary, dept_id) IN -- pair-wise
( SELECT MIN(salary), dept_id 
  FROM s_emp 
  GROUP BY dept_id );

Inline View

FROM 에 사용하는 서브쿼리
데이터 양이 많아 일부분에 대해서 조회할 때 사용

SELECT *
FROM ( SELECT * FROM s_emp WHERE title = '사원' ) e, s_dept d
WHERE e.dept_id = d.id;

Nested Subquery

두 가지 정의가 있다

  1. 실제로 중첩된 경우

    SELECT emp_name
    FROM employees
    WHERE dept_id = (
     SELECT dept_id
     FROM departments
     WHERE location_id = (
       SELECT location_id
       FROM locations
       WHERE city = 'Seoul'
     )
    );
  2. Correlated Subquery : 바깥 쿼리의 값을 참조해서 사용하는 서브쿼리

    SELECT emp_name
    FROM employees e
    WHERE salary > (
     SELECT AVG(salary)
     FROM employees
     WHERE dept_id = e.dept_id -- 바깥 쿼리의 employees 테이블을 참조
    );

    바깥 쿼리의 값(e.dpet_id)가 남지 않을 때까지 반복해서 서브쿼리를 실행한다

0개의 댓글