SELECT - SUBQUERY

Liberte Koo·2022년 12월 25일
0

Database

목록 보기
6/12

/
SELECT 조회하고싶은 컬럼
FROM 테이블
JOIN 테이블, 조인 조건
WHERE 조건
GROUP BY 그룹함수가 적용될 컬럼
HAVING 그룹핑 후 적용할 조건
ORDER BY 정렬기준 컬럼
/

SUBQUERY

  • 하나의 SELECT 문장 안에 포함된 또 하나의 SELECT 문장
  • 서브쿼리는 메인쿼리 실행 전 한 번만 실행
  • 반드시 'SELECT(소괄호)'로 묶어야 함
  • 서브쿼리와 비교할 항목은 서브쿼리의 SELECT 한 항목의 개수와 자료형이 일치해야함

/SUBQUERY 예제/

전 직원의 평균 급여보다 많은 급여를 받고 있는 직원의 사번, 이름, 직급코드, 급여를 조회

SELECT EMP_ID, EMP_NAME, DEPT_CODE, SALARY
FROM EMPLOYEE
WHERE SALARY >= (SELECT AVG(SALARY) FROM EMPLOYEE);

부서별 최고 급여를 받는 직원의 이름, 직급, 부서, 급여 조회

SELECT EMP_NAME, JOB_CODE, DEPT_NAME, SALARY
FROM EMPLOYEE
WHERE SALARY IN (SELECT MAX(SALARY) FROM EMPLOYEE GROUP BY DEPT_CODE);

전 직원의 평균 급여보다 많은 급여를 받는 직원의 사번, 이름, 직급코드, 급여

SELECT EMP_ID, EMP_NAME, JOB_CODE, SALARY
FROM EMPLOYEE
WHERE SALARY > (SELECT AVG(SALARY) FROM EMPLOYEE);

SELECT문 안에 또다른 SELECT문이 들어옴. 안에있는 SELECT문(SUBQUERY)이 먼저 수행되고, 그다음 바깥쪽 쿼리를 수행한다.

전직원의 평균급여를 조회하는 쿼리문

SELECT AVG(SALARY) FROM EMPLOYEE;

전지연 직원의 관리자의 사번, 이름, 급여를 구하라

SELECT EMP_ID, EMP_NAME, SALARY
FROM EMPLOYEE
WHERE EMP_ID=(SELECT MANAGER_ID FROM EMPLOYEE WHERE EMP_NAME='전지연');

SELECT * FROM EMPLOYEE WHERE EMP_NAME='전지연';
SUBQUERY를 위에 SELECT문에 넣어준다.

<JOIN문>

SELECT E1.EMP_ID, E1.EMP_NAME, E1.SALARY
FROM EMPLOYEE E1
JOIN EMPLOYEE E2 ON (E1.EMP_ID = E2.MANAGER_ID)
WHERE E2.EMP_NAME = '전지연';

SUBQUERY는 JOIN을 대체할 수 있지만, JOIN은 SUBQUERY를 대체할 수 없다.

1. 윤은해와 급여가 같은 사원들을 검색해서 사번, 이름, 급여 출력. 단, 윤은해는 출력X

SELECT EMP_ID, EMP_NAME, SALARY
FROM EMPLOYEE
WHERE SALARY = (SELECT SALARY FROM EMPLOYEE WHERE EMP_NAME='윤은해')
AND EMP_NAME !='윤은해';

2. EMPLOYEE 테이블에서 기본급여가 가장 많은 사람과 가장 적은사람. 사번, 사원명, 기본급여

SELECT EMP_ID, EMP_NAME, SALARY
FROM EMPLOYEE
WHERE SALARY = (SELECT MAX(SALARY) FROM EMPLOYEE)
OR SALARY = (SELECT MIN(SALARY) FROM EMPLOYEE);

3. D1, D2 부서에서 근무하는 사원들 중 D5 부서의 평균급여보다 급여가 많은 사람들의 부서코드, 사원번호, 이름, 급여

SELECT DEPT_CODE, EMP_ID, EMP_NAME, SALARY
FROM EMPLOYEE
WHERE DEPT_CODE IN ('D1', 'D2') AND
SALARY > (SELECT AVG(SALARY) FROM EMPLOYEE WHERE DEPT_CODE = 'D5' );

다중행서브쿼리(조회결과가 N행 1열)

송종기, 박나라가 속한 부서에 속한 사원들의 사번, 이름, 부서, 급여 출력

SELECT EMP_ID, EMP_NAME, DEPT_CODE, SALARY
FROM EMPLOYEE
WHERE
DEPT_CODE IN(SELECT DEPT_CODE FROM EMPLOYEE WHERE EMP_NAME IN ('송종기', '박나라'));

ANY연산자 : 여러 값중에 하나라도 TRUE면 TRUE

  • ~ > ANY : 최소값 보다 크면

    SELECT EMP_ID, EMP_NAME, SALARY
    FROM EMPLOYEE
    WHERE SALARY > ANY(2000000, 3000000, 4000000);

  • ~ < ANY : 최대값 보다 작으면

    SELECT EMP_ID, EMP_NAME, SALARY
    FROM EMPLOYEE
    WHERE SALARY < ANY(2000000, 3000000, 4000000);

  • ALL 연산자 : 여러값이 모두 TRUE면 TRUE
    -- > ALL() : 최대값보다 크면
    SELECT EMP_ID, EMP_NAME, SALARY
    FROM EMPLOYEE
    WHERE SALARY > ALL(2000000, 3000000, 4000000);
    -- 여기서는 400만원보다 크면 나온다.

  • < ALL() : 최소값보다 작으면
    SELECT EMP_ID, EMP_NAME, SALARY
    FROM EMPLOYEE
    WHERE SALARY < ALL(2000000, 3000000, 4000000);

다중열 서브쿼리 : 서브쿼리 수행결과가 1행 N열

퇴사한 직원과 같은 부서, 같은 직급에 해당하는 직원의 이름, 직급, 부서

SELECT EMP_NAME, DEPT_CODE, JOB_CODE
FROM EMPLOYEE
WHERE
(DEPT_CODE, JOB_CODE) IN (SELECT DEPT_CODE, JOB_CODE FROM EMPLOYEE WHERE ENT_YN = 'Y');

스칼라 서브쿼리

직원들 중 자기부서의 평균 급여보다 급여가 많은 직원의 이름, 부서코드, 급여 조회

SELECT EMP_NAME, DEPT_CODE, SALARY
FROM EMPLOYEE E1
WHERE SALARY > (SELECT AVG(SALARY) FROM EMPLOYEE E2 WHERE E2.DEPT_CODE = E1.DEPT_CODE);

스칼라서브쿼리 ORDER BY 절에 써보기
전직원의 사번, 이름, 부서코드 출력. 부서이름으로 오름차순정렬

SELECT EMP_ID, EMP_NAME, DEPT_CODE, (SELECT DEPT_TITLE FROM DEPARTMENT WHERE DEPT_ID=DEPT_CODE)
FROM EMPLOYEE
ORDER BY (SELECT DEPT_TITLE FROM DEPARTMENT WHERE DEPT_ID=DEPT_CODE);

SELECT * FROM DEPARTMENT ORDER BY DEPT_TITLE;

서브쿼리 FROM 절에 사용하는 방식(인라인 뷰)
서브쿼리로 나온 조회결과를 가상의 테이블로 사용
SELECT * FROM
(SELECT EMP_ID, EMP_NAME, DEPT_CODE, SALARY FROM EMPLOYEE);

TOP-N 분석 : 회사에서 연봉이 가장 높은 사람 5명의 이름, 급여 출력

  • ROWNUM : 조회된 결과에 순서대로 숫자를 붙이는 역할
  • 동작순서가 ORDER BY보다 먼저 동작
  • 그렇기땜누에 정렬된 결과를 가상의 테이블처럼 사용해 놓고 ROWNUM을 붙여서 써야지 정렬에 혼란이 안옴

    SELECT ROWNUM, EMP_NAME, SALARY FROM
    (SELECT EMP_NAME, SALARY FROM EMPLOYEE ORDER BY SALARY DESC)
    WHERE ROWNUM < 6 ;

profile
A previous generalist who strives to become a genuine Specialist.

0개의 댓글