BASHA TECH
DB#CH06. 조인과 서브쿼리 이해 본문
1. 조인의 종류
2. 내부 조인과 외부 조인
3. ANSI 조인
4. 서브 쿼리
1. 조인의 종류
: 사실 내부 조인과 외부 조인만 구분할 수 있음 됨...
- 조인 연산자에 따른 구분: 동등 조인, 안티 조인
- 조인 대상에 따른 구분: 셀프 조인 => 2개 테이블을 연결... 근데 본인 테이블을 연결하는...
- 조인 조인에 따른 구분: 내부조인&외부조인, 세미 조인, 카타시안 조인
- ANSI 조인
2. 내부 조인과 외부 조인
내부 조인 - 동등 조인, 안티 조인, 세미 조인
외부 조인 - 내부 조인이 아닌 모든 것... 결과 set의 밖을 가져온다.
▶ 내부 조인의~
- 동등 조인
: WHERE 절(where절의 기능은 row 선택)에서 등호(=) 연산자를 사용해 2개 이상의 테이블이나 뷰를 연결한 조인 값을 비교한다.
SELECT DISTINCT b.PERIOD
FROM KOR_LOAN_STATUS b
;
--문제 : 연도별 그룹화.
SELECT SUBSTR(b.PERIOD,1,4) AS years
, SUM(b.LOAN_JAN_AMT) AS tot_jan
FROM KOR_LOAN_STATUS b
GROUP BY SUBSTR(b.PERIOD,1,4)
ORDER BY years
;
-- GROUP BY에서는 AS(alias) 사용 불가
-- 연도별 총 합
-- *이 있으면 GROUP BY
-- 문제: 사원번호(사번 | employees), 이름(employees), 부서번호(부번 | employees, departments table), 부서명(departments table) 조회
SELECT COUNT(*)
FROM EMPLOYEES e
,DEPARTMENTS d
WHERE e.DEPARTMENT_ID(+) = d.DEPARTMENT_ID
-- where X => 카티시안 조인
;
-- inner한 결과를 갖고 outer 하는 거임
SELECT COUNT(*) FROM EMPLOYEES a;
--result: 107
SELECT COUNT(*) FROM DEPARTMENTS;
--result: 27
-- 모든 조인은 inner. inner한 결과에 따라 outer를 건다.
- 세미 조인
: 서브 쿼리를 사용해 서브 쿼리에 존재하는 데이터만 메인 쿼리에서 추출
> EXISTS 사용
-- 급여를 3000 이상 받는 사원이 존재하는 부서번호, 부서명 조회
SELECT d.DEPARTMENT_ID, d.DEPARTMENT_NAME
FROM DEPARTMENTS d
WHERE EXISTS ( -- WHERE절에 갖다 놓고 걸러내기만 하면 된다.. FROM 절은 nooo...~
SELECT 1 --'x'
FROM EMPLOYEES e
WHERE e.salary > 3000
AND e.DEPARTMENT_ID = d.DEPARTMENT_ID
)
;
SELECT b.DEPARTMENT_ID, MAX(b.SALARY)
FROM EMPLOYEES b
GROUP BY b.DEPARTMENT_ID
ORDER BY MAX(b.SALARY)
;
-- select에 as 걸어도 되지만 order by에서 걸어줘도 됨...
SELECT b.DEPARTMENT_ID, MAX(b.SALARY) AS sal_max
FROM EMPLOYEES b
GROUP BY b.DEPARTMENT_ID
ORDER BY sal_max, b.DEPARTMENT_ID
;
SELECT b.DEPARTMENT_ID
, MAX(b.SALARY) AS sal_max
, a.DEPARTMENT_NAME
FROM EMPLOYEES b, DEPARTMENTS a
WHERE b.SALARY > 10000
AND a.DEPARTMENT_ID = b.DEPARTMENT_ID
GROUP BY b.DEPARTMENT_ID, a.DEPARTMENT_NAME
ORDER BY sal_max, b.DEPARTMENT_ID
;
-- 1row씩... employees에 있는 값을 쓸때없이 26번이나 연산 해야함. => 비효율. 시간 엄청 든다
-- exists 107개에서 걸러낸다. => 완전 효율. 시간이 적게 든다. 잘 생각해야함. . . . . . . . . . . . . . . . .........
-- ★★★★★ 진짜 진짜 중요~~~~~ 정확하게 인지하기~~~~~~~~ EXISTS EXISTS EXISTS!
-- 단, EXISTS를 쓸 땐 전제할 조건이 있다.. => FROM에 있는 것만 SELECT 해야할 때 EXISTS를 사용해야 함..
-- 세미 조인은 무조건 사용할 수 있는 건 아님. 안 그러면 스칼라 서브 쿼리를 사용해야함..
SELECT COUNT(a.DEPARTMENT_ID)
FROM EMPLOYEES a
WHERE a.SALARY > 3000
;
SELECT COUNT(a.EMPLOYEE_ID)
FROM EMPLOYEES a
WHERE a.SALARY > 3000
;
-- 문제 : 부서 별로 3000 이상 받는 사원 수는 몇명인가?
SELECT a.DEPARTMENT_ID
,COUNT(a.DEPARTMENT_ID)
FROM EMPLOYEES a
WHERE a.SALARY >3000
GROUP BY a.DEPARTMENT_ID
-- ORDER BY
;
SELECT a.DEPARTMENT_ID
,COUNT(a.DEPARTMENT_ID) AS ecnt
FROM EMPLOYEES a
WHERE a.SALARY > 3000
GROUP BY a.DEPARTMENT_ID
ORDER BY ecnt
;
SELECT a.DEPARTMENT_ID
,COUNT(a.DEPARTMENT_ID) AS ecnt
FROM EMPLOYEES a
WHERE a.SALARY > 3000
GROUP BY a.DEPARTMENT_ID
ORDER BY ecnt
;
> IN 사용
- 안티 조인 : NOT IN, NOT EXISTS
- 셀프 조인 : 자기 자신 JOIN
- 외부 조인
> 일반 조인
> 외부 조인
- 카타시안 조인
3. ANSI 조인
Oracle JOIN :
where - 조인 조건 (연결)
- 조회 조건
ANSI JOIN :
from - 조인, 조인 조건
where - 조회 조건
- ANSI INNER JOIN
- ANSI OUTER JOIN
> Left : LEFT <OUTER> JOIN
> Right : RIGHT <OUTER> JOIN
> Full : FULL <OUTER> JOIN → (+) = (+)
- ANSI CROSS JOIN (Oracle Caratisian Join과 같다)
SELECT COUNT(DISTINCT a.employee_id)
FROM EMPLOYEES a
WHERE a.SALARY > 3000
;
SELECT a.DEPARTMENT_ID, a.DEPARTMENT_NAME
FROM DEPARTMENTS a
WHERE a.DEPARTMENT_ID IN (
SELECT b.DEPARTMENT_ID
FROM EMPLOYEES b
WHERE b.SALARY >3000
}
;
SELECT c.DEPARTMENT_ID
FROM DEPARTMENTS c
;
SELECT b.DEPARTMENT_ID
FROM EMPLOYEES b
WHERE b.SALARY >3000
ORDER BY b.DEPARTMENT_ID
;
SELECT d.DEPARTMENT_ID, d.DEPARTMENT_NAME
FROM DEPARTMENTS d
WHERE EXISTS ( -- WHERE절에 갖다 놓고 걸러내기만 하면 된다.. FROM 절은 nooo...~
SELECT 1 --'x'
FROM EMPLOYEES e
WHERE e.salary > 3000
AND e.DEPARTMENT_ID = d.DEPARTMENT_ID
)
;
--
SELECT COUNT(a.DEPARTMENT_ID)
FROM DEPARTMENTS a
, EMPLOYEES b
WHERE a.MANAGER_ID IS NULL
AND a.DEPARTMENT_ID = b.DEPARTMENT_ID -- 사원이 존재하는 부서에서 부서장이 없는 절을 찾아라 => 0개.
--즉, 사원이 존재하는 부서에서는 모두 부서장이 있다.
;
SELECT COUNT(a.DEPARTMENT_ID)
FROM DEPARTMENTS a
-- , EMPLOYEES b
WHERE a.MANAGER_ID IS NULL
-- AND a.DEPARTMENT_ID = b.DEPARTMENT_ID
; -- 16개는 안 쓰는 부서
SELECT *
FROM EMPLOYEES a
WHERE a.DEPARTMENT_ID = 20
ORDER BY a.EMPLOYEE_ID ASC
;
-- 사원 이름과 상사 이름 추출
SELECT a.EMPLOYEE_ID, a.EMP_NAME, b.EMPLOYEE_ID, b.EMP_NAME
FROM EMPLOYEES a
, EMPLOYEES b
WHERE a. DEPARTMENT_ID = b.DEPARTMENT_ID
AND a.DEPARTMENT_ID = 20
;
SELECT a.EMPLOYEE_ID, a.EMP_NAME, b.EMPLOYEE_ID, b.EMP_NAME
FROM EMPLOYEES a
, EMPLOYEES b
WHERE a. DEPARTMENT_ID = b.DEPARTMENT_ID
AND a.DEPARTMENT_ID = 20
AND a.EMPLOYEE_ID < b.EMPLOYEE_ID
;
SELECT a.EMPLOYEE_ID, a.EMP_NAME, b.EMPLOYEE_ID, b.EMP_NAME
FROM EMPLOYEES a
, EMPLOYEES b
WHERE a. DEPARTMENT_ID = b.DEPARTMENT_ID
AND a.DEPARTMENT_ID = 60
AND a.EMPLOYEE_ID < b.EMPLOYEE_ID
;
-- 문제 : 60번 부서의 사원이름과 상사의 이름 추출
-- 한개 row에서 사원이름(emp_name), 상사사원번호(m_id)
-- 다른 테이블에서 사원번호(e_id) => 이름 => 상사의 이름
-- m_id = e_id
-- 1. 60번 부서 추출
SELECT a.DEPARTMENT_ID, a.MANAGER_ID
FROM EMPLOYEES a
WHERE a.DEPARTMENT_ID = 60
;
-- 2. 60번 부서 추출
-- Self join
SELECT COUNT(*)
FROM EMPLOYEES a
, EMPLOYEES b
WHERE a.DEPARTMENT_ID = 60 -- a는 5명, b는 107명 => 5 x 107 =535명 (카티시안 곱)
AND b.DEPARTMENT_ID = 60 -- a는 5명, b는 5명 => 5 x 5 =25명
;
--
SELECT COUNT(*)
FROM EMPLOYEES a
, EMPLOYEES b
WHERE a.DEPARTMENT_ID = 60 -- a는 5명, b는 107명 => 5 x 107 =535명 (카티시안 곱)
AND a.DEPARTMENT_ID = b.DEPARTMENT_ID -- 조인 조건
AND a.MANAGER_ID = b.EMPLOYEE_ID
;
-- Outer Join
-- 문제 ?
SELECT a.DEPARTMENT_ID
, a.DEPARTMENT_NAME
, b.JOB_ID
, b.DEPARTMENT_ID
FROM DEPARTMENTS a
, JOB_HISTORY b
WHERE a.DEPARTMENT_ID = b.DEPARTMENT_ID
-- AND 올해 비교
;
SELECT a.DEPARTMENT_ID
, a.DEPARTMENT_NAME
, b.JOB_ID
, b.DEPARTMENT_ID
FROM DEPARTMENTS a
, JOB_HISTORY b
WHERE a.DEPARTMENT_ID = b.DEPARTMENT_ID(+)
-- AND 올해 비교
;
SELECT *
FROM JOB_HISTORY a -- 이력
WHERE a.EMPLOYEE_ID = 101
;
SELECT a.employee_id
, a.DEPARTMENT_ID
, a.JOB_ID
FROM EMPLOYEES a -- 현재
WHERE a.EMPLOYEE_ID = 101
;
--hola comment t'alleze vous
SELECT a.EMPLOYEE_ID
, a.EMP_NAME
, b.JOB_ID
, b.DEPARTMENT_ID
FROM EMPLOYEES a
, JOB_HISTORY b
WHERE a.EMPLOYEE_ID = b.EMPLOYEE_ID
-- AND a.DEPARTMENT_ID(현재부서) = b.DEPARTMENT_ID(예전부서) 현재부서와 과거부서가 같은 것 중 업무만 변경된 이력 조회
;
SELECT a.EMPLOYEE_ID
, a.EMP_NAME
, a.DEPARTMENT_ID -- 현재 부서
, a.JOB_ID
, b.JOB_ID
, b.DEPARTMENT_ID
FROM EMPLOYEES a
, JOB_HISTORY b
WHERE a.EMPLOYEE_ID = b.EMPLOYEE_ID -- 변경 이력이 있는 사화
AND a.DEPARTMENT_ID = b.DEPARTMENT_ID -- 부서는 같은데 job id(변경이력)만 다른 경우
;
SELECT a.EMPLOYEE_ID
, a.EMP_NAME
, a.DEPARTMENT_ID -- 현재 부서
, a.JOB_ID
, b.JOB_ID
, b.DEPARTMENT_ID
FROM EMPLOYEES a
, JOB_HISTORY b
WHERE a.EMPLOYEE_ID = b.EMPLOYEE_ID(+) -- 변경 이력이 있는 사화
-- AND a.DEPARTMENT_ID = b.DEPARTMENT_ID -- 부서는 같은데 job id(변경이력)만 다른 경우
;
SELECT a.EMPLOYEE_ID
, a.EMP_NAME
, a.DEPARTMENT_ID -- 현재 부서
, a.JOB_ID
, b.JOB_ID
, b.DEPARTMENT_ID
FROM EMPLOYEES a
, JOB_HISTORY b
WHERE a.EMPLOYEE_ID = b.EMPLOYEE_ID(+) -- 변경 이력이 있는 사화
AND a.DEPARTMENT_ID = b.DEPARTMENT_ID(+) -- 부서는 같은데 job id(변경이력)만 다른 경우
;
SELECT a.EMPLOYEE_ID, a.EMP_NAME, a.DEPARTMENT_ID, a.JOB_ID
, b.JOB_ID, b.DEPARTMENT_ID
FROM EMPLOYEES a
, JOB_HISTORY b
WHERE a.EMPLOYEE_ID = b.EMPLOYEE_ID(+)
AND a.DEPARTMENT_ID = b.DEPARTMENT_ID(+)
;
INSERT INTO EMP(empno, empnm) VALUES(400, '희동');
-- emp, dept
SELECT * FROM emp;
SELECT * FROM dept;
--100 홍길동 10 | 10 개발부
--200 고길동 20 | 20 총무부
--300 마이꼴 10 | 30 영업부
--400 희동 NULL
-- 문제 : 우리회사 모든 사원 조회 : 사원 번호, 사원명, 부서명
SELECT e.EMPNO, e.EMPNM, d.emptno, d.empnm
FROM emp e
,dept d
WHERE e.DEPTNO = d.DEPTNO(+)
;
-- 문제 : 우리 회사의 모든 부서명 조회 : 사원 번호, 사원명, 부서명
-- 부서번호, 부서명 => 조인이 필요 없다.
SELECT e.EMPNO, e.EMPNM, d.DEPTNM
FROM emp e
, dept d
WHERE e.DEPTNO(+) = d.DEPTNO
;
SELECT *
FROM EMPLOYEES a
WHERE ROWNUM < 2
;
DESC EMPLOYEES;
-- 2012년 이후 입사 사원 조회
-- 2013년 1월 1일 이후 입사
SELECT *
FROM EMPLOYEES a
WHERE a.HIRE_DATE >= '2013-01-01 12:00:00' --CASE1. HIRE_DATE를 STR로 바꾸던지, CASE2. STR을 DATE로 바꾸던지
;
SELECT *
FROM EMPLOYEES a
WHERE TO_CHAR(a.HIRE_DATE, 'YYYY-MM-DD') >= '2013-01-01'
; -- 21-6
SELECT TO_CHAR(a.HIRE_DATE), a.HIRE_DATE
FROM EMPLOYEES a
WHERE ROWNUM < 2
;
SELECT TO_CHAR(a.HIRE_DATE), a.HIRE_DATE
FROM EMPLOYEES a
WHERE ROWNUM < 2
;
-- 전체 사원 중 가장 마지막에 입사한 사원 조회
-- HIRE_DATE 값이 가장 큰 값이 사원
SELECT MAX(a.HIRE_DATE)
FROM EMPLOYEES a
;
SELECT MIN(a.HIRE_DATE) -- 가장 먼저 입사한 사람
FROM EMPLOYEES a
;
-- 2006년 이후 입사 사원 조회
-- 2007년 1월 1일 이후 입사
SELECT *
FROM EMPLOYEES a
WHERE TO_CHAR(a.HIRE_DATE, 'YYYY-MM-DD') >= '2007-01-01'
;
-- 2 TO_DATE
SELECT *
FROM EMPLOYEES a
WHERE a.HIRE_DATE >= TO_DATE('2007-01-01', 'YYYY-MM-DD')
;
-- 2003년 1월 1일 이후(조회조건) 입사한 사원
-- 사원번호, 사원명, 부서명(조인조건) 조회
SELECT a.EMPLOYEE_ID, a.EMP_NAME, b.DEPARTMENT_NAME
FROM EMPLOYEES a
, DEPARTMENTS b
WHERE a.HIRE_DATE >= TO_DATE('2003-01-01', 'YYYY-MM-DD') -- 조회 조건
AND a.DEPARTMENT_ID = b.DEPARTMENT_ID -- 조인 조건
;
SELECT a.EMPLOYEE_ID, a.EMP_NAME, b.DEPARTMENT_NAME
FROM EMPLOYEES a
, DEPARTMENTS b
WHERE a.HIRE_DATE >= TO_DATE('2003-01-01', 'YYYY-MM-DD') -- 조회 조건
AND a.DEPARTMENT_ID = b.DEPARTMENT_ID -- 조인 조건
;
--results: 17
-- ANSI Join
SELECT a.EMPLOYEE_ID, a.EMP_NAME, b.DEPARTMENT_NAME
FROM EMPLOYEES a
INNER JOIN departments b
ON (a.DEPARTMENT_ID = b.DEPARTMENT_ID) -- 조인 조건
WHERE a.HIRE_DATE >= TO_DATE('2007-01-01', 'YYYY-MM-DD')
;
SELECT a.EMPLOYEE_ID, a.EMP_NAME, b.DEPARTMENT_NAME
FROM EMPLOYEES a -- Left
JOIN departments b -- Right
ON (a.DEPARTMENT_ID = b.DEPARTMENT_ID)
WHERE a.HIRE_DATE >= TO_DATE('2007-01-01', 'YYYY-MM-DD')
;
--results: 17
SELECT a.EMPLOYEE_ID
, a.EMP_NAME
, b.DEPARTMENT_NAME
-- , b.DEPARTMENT_ID => 이렇게 쓰면 에러
, DEPARTMENT_ID
FROM EMPLOYEES a
JOIN departments b
-- ON (a.DEPARTMENT_ID = b.DEPARTMENT_ID)
USING (DEPARTMENT_ID) --USING 할 땐 column명만 기술하기, a. 하면 에러임
WHERE a.HIRE_DATE >= TO_DATE('2007-01-01', 'YYYY-MM-DD')
;
SELECT a.EMPLOYEE_ID
, a.EMP_NAME
, b.DEPARTMENT_NAME
, b.DEPARTMENT_ID -- using을 쓸거면 빼고 on절을 쓸 때는 같더라도 꼭 이렇게 써줘야 함.
FROM EMPLOYEES a
JOIN departments b
ON (a.DEPARTMENT_ID = b.DEPARTMENT_ID) --조인 조건
-- USING (DEPARTMENT_ID) --USING 할 땐 column명만 기술하기, a. 하면 에러임
WHERE a.HIRE_DATE >= TO_DATE('2007-01-01', 'YYYY-MM-DD')
;
-- emp, dept 사용한 Outer Join
-- 모든 사원 조회: 사원번호, 사원명, 부서명
SELECT a.EMPNO, a.EMPNM, b.DEPTNM
FROM emp a
, dept b
WHERE a.DEPTNO = b.DEPTNO(+)
; -- Oracle
SELECT a.empno, a.empnm, b.deptnm
FROM emp a
LEFT JOIN dept b
ON (a.deptno = b.deptno)
; -- ANSI
-- 모든 부서 조회: 사원번호, 사원명, 부서명
SELECT a.empno, a.empnm, b.deptnm
FROM emp a
, dept b
WHERE a.DEPTNO(+) = b.DEPTNO
;
SELECT a.empno, a.empnm, b.deptnm
FROM emp a
RIGHT JOIN dept b
ON (a.deptno = b.deptno)
; -- ANSI
-- 우리 회사 모든 사원과 모든 부서 조회
-- 사원번호, 사원명, 부서명 추출
SELECT *
FROM emp e
, dept d
WHERE e.DEPTNO(+) = d.DEPTNO
UNION
SELECT *
FROM emp e
, dept d
WHERE e.DEPTNO = d.DEPTNO(+)
; --Oracle
SELECT a.EMPNO
, a.EMPNM
, b.DEPTNM
FROM EMP a
FULL JOIN DEPT b
ON (a.DEPTNO = b.DEPTNO)
; -- ANSI
-- 최상위 부서(departments)에 속한 사원(employees) 수 추출
SELECT *
FROM DEPARTMENTS a
WHERE a.PARENT_ID IS NULL
;
SELECT a.DEPARTMENT_ID
FROM DEPARTMENTS a
WHERE a.PARENT_ID IS NULL
;
SELECT a.DEPARTMENT_ID, a.DEPARTMENT_NAME
FROM DEPARTMENTS a
WHERE a.DEPARTMENT_ID = 10
;
-- 위 부서의 아래 부서 확인
SELECT *
FROM DEPARTMENTS a
WHERE a.PARENT_ID = 10
;
SELECT *
FROM DEPARTMENTS a
WHERE a.PARENT_ID = (
SELECT a.DEPARTMENT_ID
FROM DEPARTMENTS a
WHERE a.PARENT_ID IS NULL
)
;
SELECT DISTINCT a.PARENT_ID
FROM DEPARTMENTS a
;
SELECT *
FROM DEPARTMENTS a
WHERE a.PARENT_ID = 100
;
SELECT *
FROM DEPARTMENTS a
WHERE a.PARENT_ID = (
SELECT a.DEPARTMENT_ID
FROM DEPARTMENTS a
WHERE a.PARENT_ID = 100
)
; --왜 에러가 날까? row 갯수가 안 맞아서 에러남
SELECT *
FROM DEPARTMENTS a
WHERE a.PARENT_ID IN ( -- IN은 다중값 연산자
SELECT a.DEPARTMENT_ID
FROM DEPARTMENTS a
WHERE a.PARENT_ID = 100
)
;
SELECT *
FROM DEPARTMENTS a
WHERE a.PARENT_ID IN ( -- =는 단일값만 IN은 다중값 연산자
SELECT a.DEPARTMENT_ID
FROM DEPARTMENTS a
WHERE a.PARENT_ID IS NULL
)
;
-- 최상위 부서 아래 부서의 개수 확인
SELECT COUNT(*)
FROM DEPARTMENTS a
WHERE a.PARENT_ID IN ( -- 상위 부서가 같은 부서
SELECT a.DEPARTMENT_ID
FROM DEPARTMENTS a
WHERE a.PARENT_ID IS NULL -- 최상위 부서
)
;
SELECT COUNT(*)
FROM EMPLOYEES a
WHERE a.DEPARTMENT_ID IN (
SELECT b.DEPARTMENT_ID
FROM DEPARTMENTS b
WHERE b.PARENT_ID IS NULL
)
;
SELECT COUNT(*)
FROM EMPLOYEES a
WHERE a.DEPARTMENT_ID = ( -- = 등호 하니까 이해하기가 더 명확해짐.
SELECT b.DEPARTMENT_ID
FROM DEPARTMENTS b
WHERE b.PARENT_ID IS NULL
)
;
-- SELECT COUNT(*) -- 사원 수
SELECT a.EMPLOYEE_ID, a.EMP_NAME -- 사원
FROM EMPLOYEES a
WHERE a.DEPARTMENT_ID = (
SELECT b.DEPARTMENT_ID
FROM DEPARTMENTS b
WHERE b.PARENT_ID IS NULL
)
;
-- SELECT COUNT(*) -- 사원 수
SELECT a.EMPLOYEE_ID, a.EMP_NAME -- 사원
, b.DEPARTMENT_NAME -- b는 메인쿼리에 없으므로 에러임
FROM EMPLOYEES a
WHERE a.DEPARTMENT_ID = (
SELECT b.DEPARTMENT_ID
FROM DEPARTMENTS b
WHERE b.PARENT_ID IS NULL
)
;
'Computer > DB' 카테고리의 다른 글
수정할 거임 0802 (0) | 2022.08.02 |
---|---|
DB#CH05. 그룹 쿼리와 집합 연산자 이해 (0) | 2022.07.28 |
DB#CH04. SQL 함수 이해 (0) | 2022.07.27 |
DB#CH03. SQL 문장 이해 (0) | 2022.07.26 |
DB#CH02. 데이터베이스를 구성하는 객체 이해 (0) | 2022.07.26 |