본문 바로가기

SQL/기본 개념

SUBQUERY(서브쿼리)

▶ 서브쿼리(SUBQUERY)

  • 서브쿼리(SUBQUERY)  : 하나의 SQL문 안에 포함된 또 다른 SQL(SELECT)문
  • 메인쿼리(기존 쿼리)를 위해 보조 역할을 하는 쿼리문
  • SELEC, FROM, WHERE, HAVING 절에서 사용 가능

  • EX) 서브쿼리 예시 : 부서코드가 노옹철 사원과 같은 소속의 사원 명, 부서코드 조회
  • 1) 사원 명이 노옹철인 사원의 부서 코드 조회
SELECT DEPT_CODE
FROM EMPLOYEE
WHERE EMP_NAME = '노옹철'; -- 결과 : D9
  • 2) 부서코드가 'D9'인 사원 조회
SELECT EMP_NAME, DEPT_CODE
FROM EMPLOYEE
WHERE DEPT_CODE = 'D9';

  • 3) 부서코드가 노옹철 사원과 같은 소속의 사원 명, 부서코드 조회
    → 1, 2단계를 하나의 쿼리로 작성
SELECT EMP_NAME, DEPT_CODE
FROM EMPLOYEE
WHERE DEPT_CODE = (SELECT DEPT_CODE FROM EMPLOYEE WHERE EMP_NAME = '노옹철');

▶ 서브쿼리 유형

  • 단일행 (+ 단일열) 서브쿼리 : 서브쿼리에서 조회한 결과 행의 개수가 1개일 때
  • 다중행 (+단일열) 서브쿼리 : 서브쿼리의에서 조회한 결과 행의 개수가 여러 개일 때
  • 다중열 서브쿼리 : 서브쿼리의 SELECT절에 나열된 컬럼의 수(= 열의 개수)가 여러 개일 때
  • 다중행 다중열 서브쿼리 : 서브쿼리에서 조회한 결과 행의 개수와 열의 개수가 여러 개일 때 
  • 상관 서브쿼리 : 서브쿼리에서 조회한 결과 값을 메인쿼리가 비교연산할 때
                              메인쿼리 테이블의 값이 변경되면 서브쿼리의 결과값도 바뀌는 서브쿼리
  • 스칼라 서브쿼리 : 상관 쿼리이면서 결과값이 하나인 서브쿼리
  • ※ 서브쿼리 유형에 따라 서브쿼리 앞에 붙은 연산자가 다름

▶ 1. 단일행 서브쿼리 (SINGLE ROW SUBQUERY)

  • 서브쿼리의 조회 결과값의 개수가 1개인 서브쿼리
  • 단일행 서브쿼리 앞에는 비교 연산자(<, >, <=, >=, =, !=, ^=, <>) 사용
-- EX) 전 직원의 급여 평균보다 많은 급여를 받는 사원의
-- 이름, 직급, 부서, 급여를 직급 순으로 정렬하여 조회
SELECT EMP_NAME, JOB_CODE, DEPT_CODE, SALARY FROM EMPLOYEE
JOIN DEPARTMENT ON (DEPT_CODE = DEPT_ID)
JOIN JOB USING (JOB_CODE)
WHERE SALARY > (SELECT FLOOR(AVG(SALARY)) FROM EMPLOYEE)
ORDER BY JOB_CODE;

-- EX) 부서별(부서가 없는 사람 포함) 급여의 합계 중 가장 큰 부서의
-- 부서명, 급여 합계 조회
SELECT DEPT_TITLE, SUM(SALARY) FROM EMPLOYEE
LEFT JOIN DEPARTMENT ON (DEPT_CODE = DEPT_ID)
WHERE SUM(SALARY) = (SELECT MAX(SUM(SALARY)) FROM EMPLOYEE GROUP BY DEPT_CODE;

▶ 2. 다중행 서브쿼리 (MULTI ROW SUBQUERY)

  • 다중행 서브쿼리(MULTI ROW SUBQUERY) : 서브쿼리의 조회 결과 값의 개수가 여러 행인 경우
  • 다중행 서브쿼리 앞에는 일반 비교 연산자 사용 X
  • IN / NOT IN : 여러 개의 결과값 중에서 한 개라도 일치하는 값이 있다면 혹은 없다면, 이라는 의미
  • > ANY / < ANY : 여러 개의 결과값 중에서 한 개라도 큰 경우, 가장 작은 값보다 큰가?
                                / 여러 개의 결과값 중에서 한 개라도 작은 경우, 가장 큰 값보다 작은가?
  • > ALL / < ALL : 여러 개의 결과값의 모든 값보다 큰 경우, 가장 큰 값보다 큰가?
                             / 여러 개의 결과값의 모든 값보다 작은 경우, 가장 작은 값보다 작은가?
  • EXISTS / NOT EXISTS : 값이 존재하는가? / 존재하지 않는가?
-- EX-1) 부서별 최고 급여를 받는 사원의 이름, 직급, 부서, 급여를 부서 순으로 정렬하여 조회
SELECT EMP_NAME, JOB_CODE, DEPT_CODE, SALARY FROM EMPLOYEE
WHERE SALARY IN (SELECT MAX(SALARY) FROM EMPLOYEE GROUP BY DEPT_CODE)
ORDER BY DEPT_CODE;

※ SELECT MAX(SALARY) FROM EMPLOYEE GROUP BY DEPT_CODE;
    : 다중 행(7행 1열) 결과값을 출력

  • EX-2) 사수에 해당하는 직원의 정보(사번, 이름, 부서명, 직급명, 구분(사수/직원) 조회
  • 1) 사수에 해당하는 사원 번호 조회
SELECT MANAGER_ID
FROM EMPLOYEE
WHERE MANAGER_ID IN NOT NULL;
-- [주의] WHERE MANAGER_ID != NULL; -> 오류 발생

  • 사원의 사번, 이름, 부서명, 직급명 조회 ( 부서 없는 사람 포함)
SELECT EMP_ID, EMP_NAME, DEPT_TITLE, JOB_NAME
FROM EMPLOYEE
LEFT JOIN DEPARTMENT ON (DEPT_CODE = DEPT_ID)
JOIN JOB USING (JOB_CODE);

  • 3) 사수에 해당하는 직원에 대한 정보 조회(이때, 구분은 '사수')
SELECT EMP_ID, EMP_NAME, DEPT_TITLE, JOB_NAME
FROM EMPLOYEE
LEFT JOIN DEPARTMENT ON (DEPT_CODE = DEPT_ID)
JOIN JOB USING (JOB_CODE)
WHERE EMP_ID IN (SELECT DISTINCT MANAGER_ID FROM EMPLOYEE WHERE MANAGER_ID IS NOT NULL);
  • 4) 일반 직원에 해당하는 사원 정보 조회(이때, 구분은 '사원')
SELECT EMP_ID, EMP_NAME, DEPT_TITLE, JOB_NAME
FROM EMPLOYEE
LEFT JOIN DEPARTMENT ON (DEPT_CODE = DEPT_ID)
JOIN JOB USING (JOB_CODE)
WHERE EMP_ID NOT IN (SELECT DISTINCT MANAGER_ID FROM EPMPLOYEE WHERE MANAGER_ID IS NOT NULL);
  • 5) 3번과 4번의 조회 결과를 하나로 합침 → SELECT절 SUBQUERY(★ ★ ★ SELECT절에도 서브쿼리 사용 가능!)
SELECT EMP_ID, EMP_NAME, DEPT_TITLE, JOB_NAME,
    CASE
        WHEN EMP_ID NOT IN (SELECT DISTINCT MANAGER_ID
                            FROM EMPLOYEE
                            WHERE MANAGER_ID IS NOT NULL)
        THEN '사원'
        ELSE '사수'
    END 구분
FROM EMPLOYEE
LEFT JOIN DEPARTMENT ON (DEPT_CODE = DEPT_ID)
JOIN JOB USING (JOB_CODE);

  • UNION 사용할 경우
SELECT EMP_ID, EMP_NAME, DEPT_TITLE, JOB_NAME
FROM EMPLOYEE
LEFT JOIN DEPARTMENT ON (DEPT_CODE = DEPT_ID)
JOIN JOB USING (JOB_CODE)
WHERE EMP_ID IN (SELECT DISTINCT MANAGER_ID FROM EMPLOYEE WHERE MANAGER_ID IS NOT NULL)

UNION

SELECT EMP_ID, EMP_NAME, DEPT_TITLE, JOB_NAME
FROM EMPLOYEE
LEFT JOIN DEPARTMENT ON (DEPT_CODE = DEPT_ID)
JOIN JOB USING (JOB_CODE)
WHERE EMP_ID NOT IN (SELECT DISTINCT MANAGER_ID FROM EPMPLOYEE WHERE MANAGER_ID IS NOT NULL);
  • EX-3) 대리 직급의 사원 중에서 과장 직급의 최소 급여보다 많이 받는 사원의 사번, 이름, 직급, 급여를 조회
  • 1) 모든 대리 직급 사원의 사번, 이름, 직급명, 급여 조회
SELECT EMP_ID, EMP_NAME, JOB_NAME, SALARY
FROM EMPLOYEE
JOIN JOB USING (JOB_CODE)
WHERE JOB_NAME = '대리';

  • 2) 모든 과장 직급 사원의 급여 조회
SELECT SALARY
FROM EMPLOYEE
JOIN JOB USIGN (JOB_CODE)
WHERE JOB_NAME = '과장'

  • 3) 모든 대리 직급 사원 중에서 과장 직급의 최소 급여보다 많이 받는 직원의
  • 3-1) MIN을 이용하여 단일행 서브쿼리를 만듦
SELECT EMP_ID, EMP_NAME, JOB_NAME, SALARY
FROM EMPLOYEE
JOIN JOB USING (JOB_CODE)
WHERE JOB_NAME = '대리'
AND SALARY > (SELECT MIN(SALARY) FROM EMPLOYEE WHERE JOB_NAME = '과장')
ORDER BY SALARY DESC;

  • 3-2) ANY를 이용하여 과장 직급 중에서 가장 급여가 적은 직원을 초과하는 대리 직급 사원 조회
SELECT EMP_ID, EMP_NAME, JOB_NAME, SALARY
FROM EMPLOYEE
JOIN JOB USING (JOB_CODE)
WHERE JOB_NAME = '대리'
AND SALARY > ANY (SELECT SALARY FROM EMPLOYEE WHERE JOB_NAME = '과장')
ORDER BY SALARY;

  • A > ANY B : A가 B의 여러 결과 중에서 하나라도 크면 TRUE → A가 B의 최소값보다 큰 경우
  • A < ANY B : A가 B의 여러 결과 중에서 하나라도 작으면 TRUE → A가 B의 최대값보다 작은 경우
-- EX) 차장 직급의 가장 높은 급여보다 많이 받는 과장 직급 사원의 정보(사번, 이름, 직급명, 급여) 조회
SELECT EMP_ID, EMP_NAME, JOB_NAME, SALARY FROM EMPLOYEE
JOIN JOB USING (JOB_CODE)
WHERE JOB_NAME = '과장'
AND SALARY > ALL (SELECT SALARY FROM EMPLOYEE NATURAL JOIN JOB WHERE JOB_NAME = '차장');

  • 서브쿼리 중첩 사용
  • EX) LOCATION 테이블에서 NATIONAL_CODE가 KO인 경우, LOCAL_CODE와
           DEPARTMENT 테이블의 LOCATION_ID가 동일한 DEPT_ID가
           EMPLOYEE 테이블의 DEPT_CODE와 동일한 사원을 구하시오.
SELECT EMP_NAME, DEPT_CODE, DEPT_ID, LOCAL_CODE
FROM EMPLOYEE
JOIN DEPARTMENT ON (DEPT_CODE = DEPT_ID)
JOIN LOCATION ON (LOCATION_ID = LOCAL_CODE)
WHERE NATIONAL_CODE = 'KO';

  • 1) LOCATION 테이블에서 NATIONAL_CODE가 KO인 경우의 LOCAL_CODE
SELECT LOCAL_CODE
FROM LOCATION
WHERE NATIONAL_CODE = 'KO';

  • 2) DEPARTMENT 테이블에서 위의 결과와 동일한 LOCATION_ID를 가진 DEPT_ID 조회
SELECT DEPT_ID
FROM DEPARTMENT
WHERE LOCATION_ID = (SELECT LOCAL_CODE FROM LOCATION WHERE NATIONAL_CODE = 'KO');

  • 3) EMPLOYEE 테이블에서 위의 결과와 동일한 DEPT_CODE를 가진 사원 정보 조회
SELECT EMP_NAME, DEPT_CODE, DEPT_ID, LOCAL_CODE
FROM EMPLOYEE
WHERE DEPT_CODE IN (SELECT DEPT_ID FROM DEPARTMENT 
                    WHERE LOCATION_ID = (SELECT LOCAL_CODE FROM LOCATION
                                         WHERE NATIONAL_CODE = 'KO');

  • → 한국에 있는 부서에서 일하는 사원 정보 조회와 같은 결과 값

▶ 다중열 서브쿼리 (단일행 = 결과값은 한 행)

  • 다중열 서브쿼리 : 서브쿼리 SELECT절에 나열된 컬럼의 수가 여러 개일 때

  • EX) 퇴사한 여직원과 같은 부서, 같은 직급에 해당하는 사원의 이름, 직급, 부서, 입사일 조회
  • 1) 퇴사한 여직원 조회
SELECT EMP_NAME, JOB_CODE, DEPT_CODE, HIRE_DATE
FROM EMPLOYEE
WHERE SUBSTR(EMP_NO,8,1) = 2;
AND ENT_YN = 'Y';

  • 2) 퇴사한 여직원과 같은 부서, 같은 직급에 해당하는 사원
SELECT EMP_NAME, JOB_CODE, DEPT_CODE, HIRE_DATE
FROM EMPLOYEE
WHERE DEPT_CODE = (SELECT DEPT_CODE FROM EMPLOYEE
                   WHERE SUBSTR(EMP_NO,8,1) = 2
                   AND ENT_YN = 'Y')
AND JOB_CODE = (SELECT JOB_CODE FROM EMPLOYEE
                WHERE SUBSTR(EMP_NO,8,1) = 2
                AND ENT_YN = 'Y');

  • 다중열 서브쿼리로 작성할 경우
SELECT EMP_NAME, JOB_CODE, DEPT_CODE, HIRE_DATE
FROM EMPLOYEE
WHERE (DEPT_CDOE, JOB_CODE) = (SELECT DEPT_CODE, JOB_CODE FROM EMPLOYEE
                               WHERE SUBSTR(EMP_NO,8,1) = 2
                               AND ENY_YN = 'Y');
  • [주의] 다중열 서브쿼리에서 WHERE절 조건 작성 시 컬럼은 반드시 순서대로 작성!

▶ 다중행 다중열 서브쿼리

  • 다중행 다중열 서브쿼리 : 서브쿼리 조회 결과 행의 개수와 열의 개수가 여러 개인 경우

  • EX) 본인 직급의 평균 급여를 받고 있는 직원의 사번, 이름, 직급, 급여를 조회
           단, 급여와 급여 평균은 만원 단위로 계산 [ TRUNC(컬럼명,-4) ]
  • 1) 급여를 200만원, 600만원 받는 직원 (200만원, 600만원이 평균 급여라고 가정)
SELECT EMP_ID, EMP_NAME, JOB_CODE, SALARY
FROM EMPLOYEE
WHERE SALARY IN (2000000, 6000000);

  • 2) 직급별 평균 급여 (만원 단위)
SELECT JOB_CODE, TRUNC(AVG(SALARY),-4)
FROM EMPLOYEE
GROUP BY JOB_CODE;

  • 3) 본인 직급의 평균 급여를 받고 있는 직원
SELECT EMP_ID, EMP_NAME, JOB_CODE, SALARY
FROM EMPLOYEE
WHERE (JOB_CODE, SALARY) IN (SELECT JOB_CODE, TRUNC(AVG(SALARY),-4) FROM EMPLOYEE
                             GROUP BY JOB_CODE);

▶ 상[호연]관 서브쿼리

  • 상관 서브쿼리에선 메인쿼리가 사용하는 테이블 값을 서브쿼리가 이용해서 결과를 만듦
  • 메인쿼리의 테이블 값이 변경되면 서브쿼리의 결과 값도 바뀌게 되는 구조

  • 1) 메인쿼리 1행 해석
  • 2) 해석된 메인쿼리 1행을 이용해서 서브쿼리 조회
  • 3) 서브쿼리 결과를 이용해서 메인쿼리 해석 중인 1행을 대상으로 조회

  • EX) 직급별 급여 평균보다 급여를 많이 받는 직원의 이름, 직급코드, 급여 조회
  • 1) 직급별 평균 급여 조회
SELECT JOB_CODE, AVG(SALARY)
FROM EMPLOYEE
GROUP BY JOB_CODE;

  • 2) 메인쿼리의 각 행을 이용해 서브쿼리 WHERE절 조건 변경
         → 다시 메인쿼리 각 행 조건 비교 → 결과 값 조회
SELECT EMP_NAME, JOB_CODE, SALARY
FROM EMPLOYEE E1
WHERE SALARY > (SELECT AVG(SALARY) FROM EMPLOYEE E2
                 WHERE E2.JOB_CODE = E1.JOB_CODE);

※ 서브쿼리가 각 JOB_CODE에 대한 평균 급여를 계산[단일 결과 값 반환]하고 있기 때문에, GROUP BY로 묶을 필요 없음

  • EX-2) 부서별 입사일이 가장 빠른 사원의
    사번, 이름, 부서명(NULL인 경우 '소속없음'), 직급명, 입사일 조회
    단, 입사일은 가장 빠른 순서로 정렬 / 퇴사한 직원은 제외
  • 1) 특정 부서에서 가장 빠른 입사일 (예를 들어 부서코드가 'D1'인 부서에서 가장 빠른 입사일)
SELECT MIN(HIRE_DATE)
FROM EMPLOYEE
WHERE DEPT_CODE = 'D1';
  • 상관쿼리로 풀이
SELECT EMP_ID, EMP_NAME, NVL(DEPT_TITLE, '소속없음')
FROM EMPLOYEE E1
LEFT JOIN DEPARTMENT ON (DEPT_CODE = DEPT_ID)
JOIN JOB USING (JOB_CODE)
WHERE HIRE_DATE = (SELECT MIN(HIRE_DATE) FROM EMPLOYEE E2
                    WHERE (E2.DEPT_CODE = E1.DEPT_CODE
                    OR (E1.DEPT_CODE IS NULL AND E2.DEPT_CODE IS NULL))
                    AND ENT_YN = 'N')
ORDER BY HIRE_DATE;
  • EX-3) 사수가 있는 직원의 사번, 이름, 부서명, 사수사번 조회
  • EXISTS : 서브쿼리에 해당하는 행이 1개라도 존재하면 조회결과에 포함
  • 1) 사수 사번과 일치하는 사번 ( 예를 들어 사수 사번이 200번인 경우)
SELECT * FROM EMPLOYEE
WHERE EMP_ID = 200;
  • 상관쿼리로 풀이
SELECT EMP_ID, EMP_NAME, DEPT_TITLE, MANAGER_ID
FROM EMPLOYEE E1
LEFT JOIN DEPARTMENT ON (DEPT_CODE = DEPT_ID)
WHERE EXISTS (SELECT EMP_ID FROM EMPLOYEE E2
               WHERE E2.EMP_ID = E1.MANAGER_ID);

※ 존재하는 사번만 조회됨

▶ 스칼라 서브쿼리

  • SELECT절에 사용되는 서브쿼리 결과로 1행(단일행)만 반환
    → SELECT절에 작성하는 단일행 서브쿼리
    ※ SQL에서 단일 값을 '스칼라'라고 함
-- EX) 각 직원들이 속한 직급의 평균 급여 조회 (스칼라 + 상관쿼리)
SELECT EMP_NAME, JOB_CODE, SALARY, (SELECT FLOOR(AVG(SALARY)) FROM EMPLOYEE E2 WHERE E2.JOB_CODE = E1.JOB_CODE) 평균급여
FROM EMPLOYEE E1
-- EX-2) 모든 사원의 사번, 이름, 관리자 사번, 관리자명을 조회
-- 단, 관리자가 없는 경우, '없음'으로 표시
SELECT EMP_ID 사번, EMP_NAME 사원명, NVL(MANAGER_ID,'없음') "관리자 사번", 
NVL((SELECT E2.EMP_NAME FROM EMPLOYEE E2 WHERE E2.EMP_ID = E1.MANAGER_ID),'없음') '관리자명'
FROM EMPLOYEE E1;

▶ 인라인 뷰 (INLINE-VIEW)

  • FROM절에서 서브쿼리를 사용하는 경우로, 서브쿼리가 만든 결과의 집합(RESULT SET)을
    테이블 대신에 사용

  • EX) 인라인 뷰를 활용한 TOP-N 분석
    전 직원 중 급여가 높은 상위 5명의 순위, 이름, 급여 조회
  • 1) 급여 높은 순서로 조회
SELECT SALARY
FROM EMPLOYEE
ORDER BY SALARY DESC;

  • 2) 조회되는 행 앞에 1부터 순서대로 1씩 증가하는 번호 붙이기
    - ROWNUM : 행 번호를 나타내는 가상 컬럼(1부터 1씩 증가)
SELECT ROWNUM, EMP_NAME
FROM EMPLOYEE;

  • 3) ROWNUM을 조건에 사용하기
SELECT ROWNUM, EMP_NAME
FROM EMPLOYEE
WHERE ROWNUM <= 5;

  • 4) 1,2,3번을 토대로 급여 상위 5명 조회 시도
SELECT ROWNUM, EMP_NAME, SALARY
FROM EMPLOYEE
WHERE ROWNUM <= 5
ORDER BY SALARY DESC;

※ SELECT문 해석 순서를 고려하지 않아서 원하는 결과 값이 조회되지 않았음
    → 이를 해결하기 위해서 [인라인 뷰] 필요

  • 해결 1) 급여 내림차순 조회
SELECT EMP_NAME, SALARY
FROM EMPLOYEE
ORDER BY SALARY DESC;

※ 조회 결과(RESULT SET)를 가상의 테이블(= VIEW)로 취급할 예정

  • 2) 해결 1번의 조회 결과를 FROM절에 사용한 후 상위 5행만 조회
SELECT EMP_NAME, SALARY
FROM (SELECT EMP_NAME, SALARY FROM EMPLOYEE ORDER BY SALARY DESC)
--> FROM절 내부에 포함된 가상의 테이블 == 인라인 뷰
WHERE ROWNUM <= 5;

-- EX) 평균 급여가 상위 3위 안에 드는 부서의 부서코드와 부서명, 평균 급여 조회
SELECT ROWNUM, DEPT_CODE, DEPT_TITLE, 평균급여
FROM (SELECT DEPT_CODE, DEPT_TITLE, FLOOR(AVG(SALARY)) 평균급여 FROM EMPLOYEE
       LEFT JOIN DEPARTMENT ON (DEPT_CODE = DEPT_ID)
       GROUP BY DEPT_CODE, DEPT_TITLE
       ORDER BY 평균급여 DESC)
WHERE ROWNUM <= 3;

※ FROM절에서 평균급여 별칭 부여 후, 내부쿼리의 ORDER BY절과 메인쿼리의 SELECT절에서 별칭 사용
메인쿼리의 SELECT절에서 별칭 미사용 시 오류 발생

▶ WITH

  • 서브쿼리에 이름을 붙여주고 사용 시 이름을 사용
  • 인라인 뷰로 사용될 서브쿼리에 주로 사용됨 / 실행속도가 빨라지는 장점이 있음
-- EX) 전 직원의 급여 높은 순으로 순위, 이름, 급여 조회
WITH TOP_SAL AS (SELECT EMP_NAME, SALARY FROM EMPLOYEE
                 ORDER BY SALARY DESC)
                 
SELECT ROWNUM, EMP_NAME, SALARY
FROM TOP_SAL;

※ WITH로 이름 지정하고 ;로 마감처리하면 안 됨 [오류 발생]

▶ RANK( ) OVER / DENSE_RANK( ) OVER

  • RANK( ) OVER : 동일한 순위 이후의 등수를 동일한 인원 수만큼 건너뛰고 순위 계산
                                예를 들어, 공동 1위가 2명이면 다음 순위는 3위
SELECT RANK() OVER(ORDER BY SALARY DESC) AS 순위, EMP_NAME, SALARY
FROM EMPLOYEE;

※ 19등이 2명일 때, 바로 다음 순위 21등으로 건너 뜀

  • DENSE_RANK( ) OVER : 동일한 순위 이후의 등수를 이후의 순위로 계산
                                              예를 들어, 공동 1위가 2명이어도 다음 순위는 2위
SELECT DENSE_RANK() OVER(ORDER BY SALARY DESC) AS 순위, EMP_NAME, SALARY
FROM EMPLOYEE;

※ 19등이 2명일 때, 바로 다음 순위 20등

'SQL > 기본 개념' 카테고리의 다른 글

DDL (DATA DEFINITION LANGUAGE) _ 데이터 정의 언어  (0) 2024.12.16
DML (Data Manipulation Language) _ 데이터 조작 언어  (0) 2024.12.16
JOIN  (0) 2024.12.16
GROUP BY / HAVING  (0) 2024.12.16
그룹(GROUP) 함수  (0) 2024.12.16