목차
1. 단일행 (+ 단일열) 서브쿼리 (SINGLE ROW SUBQUERY)
2. 다중행 서브쿼리 (MULTI ROW SUBQUERY)
3.(단일행) 다중열 서브쿼리
4. 다중행 다중열 서브쿼리
5. 상[호연]관 서브쿼리
6. 스칼라 서브쿼리
7. 인라인 뷰(INLINE-VIEW)
8. WITH
9. RANK() OVER / DENSE_RANK() OVER
✍SUBQUERY( 서브쿼리)
하나의 SQL문 안에 포함된 또다른 SQL문
메인쿼리(기존쿼리)를 위해 보조 역할을 하는 쿼리문
SELECT, FROM, WHERE, HAVGIN 절에서 사용가능
: SELECT 문장 안에 포함된 또 다른 SELECT 문장으로 메인 쿼리가 실행되기 전 한 번만 실행된다.
비교 연산자의 오른쪽(WHERE절,GROUP BY절 등 한정,) 에 기술해야 하며 반드시 괄호로 묶어야 한다.
서브쿼리와 비교할 항목은 반드시 서브쿼리의 SELECT한 항목의 개수와 자료형을 일치시켜야 한다.
SUB
: 보조
QUERY
: 질의
SELECT EMP_ID, EMP_NAME, JOB_CODE, SALARY
FROM EMPLOYEE
WHERE SALARY >= (SELECT AVG(SALARY) FROM EMPLOYEE);
: 서브쿼리
SELECT - 메인쿼리
예제 1. 전 직원의 평균 급여보다 많은 급여를 받고 있는 직원의 사번, 이름, 직급코드, 급여 조회
1) 전 직원의 평균 급여 조회하기
SELECT AVG(SALARY) FROM EMPLOYEE;
2) 직원들중 급여가 3047663원 이상인 사원들의 사번, 이름, 직급코드, 급여 조회
SELECT EMP_ID, EMP_NAME, JOB_CODE, SALARY
FROM EMPLOYEE
WHERE SALARY >= 3047663;
3047663 == 1)구문
3) 전 직원의 평균 급여보다 많은 급여를 받고 있는 직원 조회
--> 위의 2단계를 하나의 쿼리로 가능하다!! --> 1) 쿼리문을 서브쿼리로!!
SELECT EMP_ID, EMP_NAME, JOB_CODE, SALARY
FROM EMPLOYEE
WHERE SALARY >= (SELECT AVG(SALARY) FROM EMPLOYEE);
[서브 쿼리 유형]
(SELECT 한정)
- 단일행 서브쿼리 : 서브쿼리의 조회 결과 값의 개수가 1개일 때
- 다중행 서브쿼리 : 서브쿼리의 조회 결과 값의 개수가 여러개일 때
- 다중열 서브쿼리 : 서브쿼리의 SELECT 절에 자열된 항목수가 여러개 일 때
- 다중행 다중열 서브쿼리 : 조회 결과 행 수와 열 수가 여러개일 때
- 상관 서브쿼리 : 서브쿼리가 만든 결과 값을 메인 쿼리가 비교 연산할 때
메인 쿼리 테이블의 값이 변경되면 서브쿼리의 결과값도 바뀌는 서브쿼리 - 스칼라 서브쿼리 : 상관 쿼리이면서 결과 값이 하나인 서브쿼리
* 구문에서 서브쿼리만 선택해서 실행하면 그부분에 대한 값만 나온다
* 서브쿼리 유형에 따라 서브쿼리 앞에 붙은 연산자가 다름
🚩 단일행 (+ 단일열) 서브쿼리 (SINGLE ROW SUBQUERY)
서브쿼리의 조회 결과 값의 개수가 1개인 서브쿼리
단일행 서브쿼리 앞에는 비교 연산자 사용
: <, >, <=, >=, =, !=/^=/<>
예제1. 가장 적은 급여를 받는 직원의 사번, 이름, 직급, 부서코드, 급여, 입사일을 조회
SELECT EMP_ID, EMP_NAME, JOB_CODE, DEPT_CODE, SALARY, HIRE_DATE
FROM EMPLOYEE
WHERE SALARY = (SELECT MIN(SALARY) FROM EMPLOYEE);
예제2. A 사원의 급여보다 많이 받는 직원의 사번, 이름, 부서, 직급, 급여를 조회
SELECT EMP_ID, EMP_NAME, DEPT_CODE, JOB_CODE, SALARY
FROM EMPLOYEE
WHERE SALARY > (SELECT SALARY FROM EMPLOYEE
WHERE EMP_NAME = 'A');
예제1. 가장 적은 급여를 받는 직원의 사번, 이름, 직급, 부서코드, 급여, 입사일을 조회
SELECT SUM(SALARY)
FROM EMPLOYEE
GROUP BY DEPT_CODE;
👉 GROUP BY
: 해당 코드별 그룹대로 계산해라
예제2. 부서별(부서가 없는 사람 포함) 급여의 합계 중 가장 큰 부서의 부서명, 급여 합계를 조회
1) 부서별 급여 합 중 가장 큰값 조회
1-1) 부서별 급여 합
SELECT SUM(SALARY)
FROM EMPLOYEE
GROUP BY DEPT_CODE;
1-2)부서별 급여 합 중 가장 큰 값
SELECT MAX( SUM(SALARY))
FROM EMPLOYEE
GROUP BY DEPT_CODE;
2) 부서별 급여합이 17700000인 부서의 부서명과 급여 합 조회
SELECT DEPT_TITLE, SUM(SALARY)
FROM EMPLOYEE
LEFT JOIN DEPARTMENT ON(DEPT_CODE = DEPT_ID)
GROUP BY DEPT_TITLE HAVING SUM(SALARY) = 17700000;
➡ LEFT JOIN으로 EMPLOYEE에 있는 모든 값을 조인한다. 부서가 없는 사람도 포함
➡ GROUP BY절의 조건은 HAVING으로 한다.
3) 위의 두 서브쿼리 합쳐 부서별 급여 합이 큰 부서의 부서명, 급여 합 조회
SELECT DEPT_TITLE, SUM(SALARY)
FROM EMPLOYEE
LEFT JOIN DEPARTMENT ON(DEPT_CODE = DEPT_ID)
GROUP BY DEPT_TITLE HAVING SUM(SALARY) = ( SELECT MAX( SUM(SALARY))
FROM EMPLOYEE
GROUP BY DEPT_CODE
);
🚩 다중행 서브쿼리 (MULTI ROW SUBQUERY)
서브쿼리의 조회 결과 값의 개수가 여러행일 때
- 다중행 서브쿼리 앞에는 일반 비교연산자 사용
- IN / NOT IN : 여러 개의 결과값 중에서 한 개라도 일치하는 값이 있다면
혹은 없다면 이라는 의미(가장 많이 사용!) - > ANY, < ANY : 여러개의 결과값 중에서 한개라도 큰 / 작은 경우
가장 작은 값보다 큰가? / 가장 큰 값 보다 작은가? - > ALL, < ALL : 여러개의 결과값의 모든 값보다 큰 / 작은 경우
가장 큰 값 보다 큰가? / 가장 작은 값 보다 작은가? - EXISTS / NOT EXISTS : 값이 존재하는가? / 존재하지 않는가?
1) IN / NOT IN
여러 개의 결과값 중에서 한 개라도 일치하는 값이 있다면
혹은 없다면 이라는 의미(가장 많이 사용!)
예제1. 사수에 해당하는 직원에 대해 조회 사번, 이름, 부서명, 직급명, 구분(사수 / 직원)
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 EMPLOYEE
WHERE MANAGER_ID IS NOT NULL) ;
👉 UNION
: 여러 개의 쿼리 결과를 합치는 연산자로 중복된 영역은 제외하여 합침
1-1) CASE END문 사용
SELECT EMP_ID, EMP_NAME, DEPT_TITLE, JOB_NAME,
CASE
WHEN EMP_ID IN (SELECT DISTINCT MANAGER_ID
FROM EMPLOYEE
WHERE MANAGER_ID IS NOT NULL )
THEN '사수'
ELSE '사원'
END AS 구분
FROM EMPLOYEE
LEFT JOIN DEPARTMENT ON(DEPT_CODE = DEPT_ID)
JOIN JOB USING(JOB_CODE);
➡ 괄호가 없이 되고 CASE 열고 END 닫았다
CASE END를 하나의 구문으로 보고 그래서 그 END 뒤에 별칭 붙이기
SELECT절에도 서브 쿼리를 쓸 수 있다.
2) > ANY, < 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
JOIN JOB USING(JOB_CODE)
WHERE JOB_NAME = '과장');
3) >ALL, < ALL
여러개의 결과값의 모든 값보다 큰 / 작은 경우
가장 큰 값 보다 큰가? / 가장 작은 값 보다 작은가?
SELECT EMP_ID, EMP_NAME, JOB_NAME, SALARY
FROM EMPLOYEE NATURAL
JOIN JOB --EMPLOYEE와 JOB의 공통컬럼인 JOB_CODE가 자연 조인
WHERE JOB_NAME = '과장'
AND SALARY > ALL (SELECT SALARY
FROM EMPLOYEE
NATURALJOIN JOB WHERE JOB_NAME = '차장');
🚩 (단일행) 다중열 서브쿼리
(단일행 = 결과값은 한 행)
서브쿼리 SELECT 절에 나열된 컬럼 수가 여러개 일 때
예제1. 77년생 여자 사원과 동일한 부서이면서 동일한 사수를 가지고 있는 사원을 조회하시오.
사번, 이름, 부서코드, 사수번호, 주민번호, 고용일
1) 부서코드
SELECT DEPT_CODE
FROM EMPLOYEE
JOIN DEPARTMENT ON (DEPT_CODE = DEPT_ID)
WHERE SUBSTR(EMP_NO,1,2) = '77'
AND SUBSTR(EMP_NO,8,1) = '2';
2) 동일 사수
SELECT MANAGER_ID
FROM EMPLOYEE
JOIN DEPARTMENT ON (DEPT_CODE = DEPT_ID)
WHERE SUBSTR(EMP_NO,1,2) = '77'
AND SUBSTR(EMP_NO,8,1) = '2';
3) 최종
SELECT EMP_NAME, JOB_CODE, DEPT_CODE, HIRE_DATE
FROM EMPLOYEE
WHERE (DEPT_CODE, JOB_CODE) = (SELECT DEPT_CODE, JOB_CODE
FROM EMPLOYEE
WHERE ENT_YN = 'Y'
AND SUBSTR(EMP_NO, 8, 1) = '2')
AND EMP_NAME != (SELECT EMP_NAME
FROM EMPLOYEE
WHERE ENT_YN = 'Y'
AND SUBSTR(EMP_NO, 8, 1) = '2');
👉다중열
👉단일행
🚩 다중행 다중열 서브쿼리
서브쿼리 조회 결과 행 수와 열 수가 여러개 일 때
예제1. 본인 직급의 평균 급여를 받고 있는 직원
본인 직급의 평균 급여를 받고 있는 직원의
사번, 이름, 직급, 급여를 조회하세요
단, 급여와 급여 평균은 만원단위로 계산하세요 TRUNC(컬럼명, -4) (TRUNC : 절삭처리)
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);
👉TRUNC
: TRUNC일때는 절삭 처리 소수점 아래자리를 처리해준다.
🚩⭐상[호연]관 서브쿼리⭐
상관 쿼리는 메인쿼리가 사용하는 테이블값을 서브쿼리가 이용해서 결과를 만든다.
메인쿼리의 테이블값이 변경되면 서브쿼리의 결과값도 바뀌게 되는 구조이다.
== 메인 쿼리의 결과가 서브쿼리에 영향을 미치는 쿼리
(메인쿼리와 서브쿼리가 서로 상호연관 관계)
실행순서
상관쿼리는 먼저 메인쿼리 한 행을 조회하고
해당 행이 서브쿼리의 조건을 충족하는지 확인하여 SELECT를 진행한다.
==> 메인쿼리 수행 후 서브쿼리 수행
기존 서브쿼리 SQL 해석 순서
1) 서브쿼리 2) 메인쿼리
상관 서브쿼리 SQL 해석 순서
1) 메인쿼리 2) 서브쿼리
예제1. 사수가 있는 직원의 사번, 이름, 부서코드, 사수사번 조회
--> 퇴사한 사람인 MANAGER_ID 100인 사람을 제외
SELECT EMP_ID, EMP_NAME, DEPT_CODE, MANAGER_ID
FROM EMPLOYEE E1
WHERE EXISTS ( SELECT EMP_ID
FROM EMPLOYEE E2
WHERE E1.MANAGER_ID = E2.EMP_ID);
➡ 서브쿼리에 작성된 E1 때문에 서브쿼리가 먼저 실행될 수 없다.
해석 순서
FROM -> WHERE -> 내부 서브쿼리 FROM -> WHERE) ->SELECT
E1, E2 테이블을 만들어
메인쿼리에서 한 행을 해석한 후 그 결과를 가지고 서브쿼리에서 해석한다.
E1에서 조회한 결과를 서브쿼리 E2에서
예제2. 직급별 급여 평균보다 급여를 많이 받는 직원의 이름, 직급코드, 급여 조회
SELECT EMP_NAME, JOB_CODE, SALARY
FROM EMPLOYEE E1
WHERE SALARY > (SELECT AVG(SALARY)
FROM EMPLIOYEE E2
GROUP BY E2.JOB_CODE = E1.JOB_CODE);
➡ 먼저 첫번째 행인 사람의 값을 조회해서 서브쿼리에서 그 직급코드가 같은 경우의 급여 평균을 조회
그래서 메인 쿼리의 비교 대상 SALARY가 서브쿼리의 급여 평균보다 높은면 값 반환
➡ SELECT 문은 테이블 내에서 조건에 맞는 행을 한 번에 조회 하는 것이 아닌
테이블의 한 행씩 접근하여 조건을 하나하나 따져 일치하면 조회 결과 집합(RESULT SET)에
해당 행을 추가하여 모든 행을 따져본 후 결과를 조회
예제3. 부서별 입사일이 가장 빠른 사원의
사번, 이름, 부서명(NULL이면 '소속없음'), 직급명, 입사일을 조회하고
입사일이 빠른 순으로 조회하세요 (ORDER BY)
단, 퇴사한 직원은 제외하고 조회하세요
1) 서브쿼리에 GROUP BY 절 사용
SELECT EMP_ID, EMP_NAME, NVL(DEPT_TITLE, '소속없음'), JOB_NAME, HIRE_DATE
FROM EMPLOYEE
LEFT JOIN DEPARTMENT ON (DEPT_CODE = DEPT_ID)
JOIN JOB USING(JOB_CODE)WHERE HIRE_DATE IN (SELECT MIN(HIRE_DATE)
FROM EMPLOYEE
WHERE EMP_YN = 'N' --'Y'가 퇴사
GROUP BY DEPT_CODE);
👉 NVL
: 컬럼 값이 NULL일 경우 다른 값으로 변경, NVL(컬럼명, NULL일 때 변경할 값)
👉 LEFT JOIN
이유: JOIN 왼 쪽에 있는 EMPLOYEE의 모든걸 합친다는 의미로 부서코드가 NULL인 값도 합친다.
퇴사한 직원이라는 조건은 서브쿼리에 들어가야한다.
--> 결과는 맞게 나왔으나, 조건이 불명확하다.
이유: 서브쿼리 결과가 단순히 입사일만을 조회했기 때문에 만약 같은 입사일인 사람이 있었다면 모두 조회되었을 것이다.
부서와 상관없이 입사일로만 따졌기때문에 최종결과에 다 포함이 되어버려 문제가 생긴다.
해결법
2) 상관쿼리
SELECT EMP_ID, EMP_NAME, NVL(DEPT_TITLE, '소속없음'), JOB_NAME, HIRE_DATE
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 ENT_YN = 'N'
AND E2.DEPT_CODE = E1.DEPT_CODE
OR (E1.DEPT_CODE IS NULL AND E2.DEPT_CODE IS NULL));
➡ 메인쿼리 해석
테이블을 합친 후 조건에 맞는 고용일이 빠른 사원들을 조회
➡ 서브쿼리 해석
퇴사하지 않았고
메인쿼리의 부서코드와 서브쿼리의 부서코드가 같은 경우에
NULL 값도 포함되어야하기때문에 조건을 추가
고용일이 가장 빠른 사원을 조회한다.
🚩 스칼라 서브쿼리
SELECT 절 단일행 서브쿼리
SELECT절에 사용되는 서브쿼리 결과로 1행만 반환
서브쿼리가 한 행만 나오는 스칼라 서브쿼리
SQL에서 단일 값을 '스칼라'라고 한다.
보통 상관쿼리와 같이 쓰인다.
예제1. 각 직원들이 속한 직급의 급여 평균 조회
스칼라 서브쿼리 + 상관쿼리
SELECT EMP_NAME, JOB_NAME,
( SELECT ROUND(AVG(SALARY)) FROM EMPLOYEE E2
WHERE E2.JOB_CODE = E1.JOB_CODE) "직급별 급여평균"
FROM EMPLOYEE E1
JOIN JOB ON(E1.JOB_CODE = JOB.JOB_CODE)
ORDER BY E1.JOB_CODE;
👉 ON : JOIN에 사용할 컬럼명이 다른경우 ON()을 사용
별칭이 붙었을때는 USING이 안되기 때문에 ON 사용
그리고 JOB테이블의 JOB_CODE이기 때문에 JOB이용
➡JOIN JOB ON(E1.JOB_CODE = JOB.JOB_CODE)
EMPLOYEE와 JOB 테이블에 다 JOB_CODE가 있다.
JOB테이블에 별칭을 지어주지 않았기때문에 테이블명을 넣는다.
예제2. 모든 사원의 사번, 이름, 관리자사번, 관리자명을 조회
단 관리자가 없는 경우 '없음'으로 표시
(스칼라 + 상관 쿼리)
SELECT EMP_NAME, JOB_CODE, SALARY
FROM EMPLOYEE E1
WHERE SALARY > (SELECT AVG(SALARY)
FROM EMPLIOYEE E2
GROUP BY E2.JOB_CODE = E1.JOB_CODE);
➡ 조회결과가 값이 하나다 - 스칼라
➡ 행별로 값이 다르다 - 상관쿼리
➡ 메인테이블에 있는 매니저아이디와 서브쿼리에 있는 사번이 같은 사람을 조회한다.
관리자가 없는거니깐 없음 처리를 위해 NVL
🚩⭐인라인 뷰(INLINE-VIEW) ⭐
가장 많이 사용
FROM 절에서 서브쿼리를 사용하는 경우로
서브쿼리가 만든 결과의 집합(RESULT SET)을 테이블 대신에 사용한다.
VIEW
: 가상의 테이블(진짜 테이블이 아님)
ex) SELECT 결과(RESULT SET)
SELECT EMP_NAME, SALARY FROM EMPLOYEE;
예제1. 인라인뷰를 활용한 TOP-N분석 전 직원 중 급여가 높은 상위 5명의
순위, 이름, 급여 조회
1) 전 직원의 급여 내림차순 조회
SELECT EMP_NAME, SALARY
FROM EMPLOYEE
ORDER BY SALARY DESC;
2) 조회되는 행의 순서를 나타내는 가상의 컬럼 ROWNUM
SELECT ROWNUM, EMP_NAME
FROM EMPLOYEE
WHERE ROWNUM <= 5;
➡1~5까지 반환하기 위해서는 5,4,3,2,1로 '이하'인 <= 사용
3) 상위 5명 조회
SELECT ROWNUM, EMP_NAME, SALARY
FROM EMPLOYEE
WHERE ROWNUM <= 5
ORDER BY SALARY DESC;
➡ 문제점 : SELECT 해석 순서
해석 순서 : FROM - WHERE - SELECT - ORDER BY
서브쿼리 결과를 테이블로 사용한다.
4) 조치 내용 == 인라인 뷰로 해결
SELECT ROWNUM, EMP_NAME, SALARY
FROM ( SELECT EMP_NAME, SALARY
FROM EMPLOYEE
ORDER BY SALARY DESC )
WHERE ROWNUM <= 5;
예제2. 급여 평균이 3위 안에 드는 부서의 부서코드와 부서명, 평균급여를 조회
SELECT *
FROM (
SELECT DEPT_CODE, DEPT_TITLE, FLOOR(AVG(SALARY)) "평균급여"
FROM EMPLOYEE
JOIN DEPARTMENT ON (DEPT_CODE = DEPT_ID)
GROUP BY DEPT_CODE, DEPT_TITLE
ORDER BY "평균급여" DESC)
WHERE ROWNUM <= 3;
➡ SELECT절에 단일행, 그룹함수가 혼용되어 있는 경우 단일행 부분을 모두 GROUP BY절에 그대로 작성해야 한다.
🚩 WITH
서브쿼리에 이름을 붙여주고 사용시 이름을 사용하게 함
인라인뷰로 사용될 서브쿼리에 주로 사용됨
실행 속도도 빨라진다는 장점이 있다.
예제1. 전 직원의 급여 순위
1)순위, 이름, 급여 조회
SELECT ROWNUM 순위, EMP_NAME 이름, SALARY 급여
FROM (SELECT EMP_NAME, SALARY FROM EMPLOYEE
ORDER BY SALARY DESC);
2) WITH
WITH SALARY_RANK AS (
SELECT EMP_NAME, SALARY FROM EMPLOYEE
ORDER BY SALARY DESC
)
SELECT ROWNUM 순위, EMP_NAME 이름, SALARY 급여
FROM SALARY_RANK;
🚩 RANK() OVER / DENSE_RANK() OVER
1) RANK() OVER
동일한 순위 이후의 등수를 동일한 인원 수 만큼 건너뛰고 순위 계산
EX) 공동 1위가 2명이면 다음 순위는 2위가 아니라 3위
공동 순위 포함
SELECT EMP_NAME, SALARY
FROM (SELECT EMP_NAME, SALARY FROM EMPLOYEE
ORDER BY SALARY DESC);
RANK() OVER 적용 (
SELECT RANK() OVER( ORDER BY SALARY DESC) 순위, EMP_NAME, SALARY
FROM EMPLOYEE;
-> 급여 내림차순 순으로 순위를 매기는 컬럼
결과: 순위에서 18, 19, 19, 21
2) DENSE_RANK() OVER
동일한 순위 이후의 등수를 이후의 순위로 계산
EX) 공동 1위가 2명이어도 다음 순위는 2위
공동 순위 미포함
SELECT DENSE_RANK() OVER( ORDER BY SALARY DESC) 순위, EMP_NAME, SALARY
FROM EMPLOYEE;
결과: 순위에서 18, 19, 19, 20
'Backend > Oracle' 카테고리의 다른 글
[DB] DDL : CREATE, 제약조건 CHECK (0) | 2021.09.27 |
---|---|
[DB] DML (INSERT, UPDATE, MERGE, DELETE) (0) | 2021.09.25 |
[DB] JOIN (0) | 2021.09.23 |
[DB] SELECT문 해석 순서 | GROUP BY, ORDER BY,HAVING, 집계 함수 (0) | 2021.09.21 |
[DB] 함수(Function)_단일행, 그룹 (0) | 2021.09.18 |