기타/[하나로_수업]
5/23
hyunnn_00
2023. 5. 23. 16:43
서브쿼리
- FROM절 서브쿼리 뒤에서
- 다중 열 서브쿼리
- 쿼리 실행 결과가 여러 개의 열로 출력
- 여러 개의 열 비교
-- FROM 절 뒤에 사용하는 서브쿼리 -- 인라인 뷰 = SQL문 실행 결과를 마치 테이블처럼 사용 SELECT E30.EMPNO, E30.ENAME, D.DEPTNO,D.DNAME FROM (SELECT * FROM EMP WHERE DEPTNO = 30) E30 , (SELECT * FROM DEPT) D WHERE E30.DEPTNO = D.deptno; ---------------------------------------------------------- -- 인라인 뷰에 사용하는 SQL문이 길어진다면 WITH 절 사용하면 됨 -- 가독성을 높이기 위한 목적 -- WITH 절에서 미리 내용을 파악할 수 있음 => SELECT 문을 읽으먼 도움이 됨 WITH E30 AS (SELECT * FROM EMP WHERE DEPTNO = 30), D AS (SELECT * FROM DEPT) SELECT E30.EMPNO, E30.ENAME, D.DEPTNO, D.DNAME FROM E30, D WHERE E30.DEPTNO = D.DEPTNO;
- SELECT 절에서
- 스칼라 서브쿼리
- 하나의 열처럼 사용
- 새로운 말을 만든다는 개념
- 서브쿼리도 반드시 하나의 결과만 반환하도록 작성해야 함
-- SELECT 절 뒤에서 사용하는 서브쿼리 = 스칼라 서브쿼리 = 열처럼 사용 SELECT DNAME FROM EMP A, DEPT B WHERE A.DEPTNO = B.DEPTNO; SELECT GRADE FROM EMP C, SALGRADE D WHERE C.SAL BETWEEN D.LOSAL AND D.HISAL; SELECT EMPNO, ENAME, JOB, SAL, (SELECT GRADE FROM SALGRADE WHERE A.SAL BETWEEN LOSAL AND HISAL) AS GRADE, DEPTNO, (SELECT DNAME FROM DEPT B WHERE A.DEPTNO = B.DEPTNO) AS DNAME FROM EMP A;
- 스칼라 서브쿼리
6. 데이터 조작어
DML
- INSERT
- UPDATE
- DELETE
TCL
- COMMIT
- ROLLBACK
DDL
- CREATE
- ALTER
- RENAME
- TRUNCATE
- DROP
※ DML은 TCL과 함께 사용함
※ DDL은 혼자 사용 가능, 자동 commit됨
- 테이블 만들기 CREATE TABLE
- 테이블 삭제 DROP TABLE
- 데이터 추가 INSERT INTO 테이블 이름(열1, 열2, … , 열N) VALUES (값1, 값2,, … , 값N)
- 테이블 만들기 CREATE TABLE
- 테이블 삭제 DROP TABLE
- 데이터 추가 INSERT INTO 테이블 이름(열1, 열2, … , 열N) VALUES (값1, 값2,, … , 값N)
7. 트랜잭션 제어(TCL)
- ROLLBACK : 트랜잭션을 취소하고 싶을 때
- COMMIT : 트랜잭션을 영원히 반영하고 싶을 때
- 세션
- 어떤 활동을 위한 시간이나 기간
- 한 계정이 여러 세션 사용 가능
- 한 세션 안에서 하나 이상의 트랜잭션이 있음
8. 데이터 정의어(DDL)
- DML과 달리, 자동으로 COMMIT 수행됨
- ROLLBACK을 통한 실행 취소 불가
- 테이블 생성 CREATE TABLE
- 문자로 시작 & 숫자로 시작 x
- 같은 사용자 소유의 테이블 이름, 열 이름 중복 불가
- SQL 키워드 사용 불가
- 테이블 변경 ALTER TABLE
- 테이블에 열 추가 ADD
- 열 이름 변경 RENAME
- 열 자료형 변경 MODIFY
- 특정 열 삭제 DROP
```sql
-- 다중행 서브쿼리(계속)
-- EXISTS 연산자 - 서브쿼리에 결과가 있으면 TRUE 없으면 FALSE
SELECT * FROM DEPT WHERE DEPTNO = 10; -- 결과가 하나 존재하기 때문에 TRUE
-- EXISTS 연산자에서 TRUE로 사용이 되면 앞에 SQL 문이 정상적으로 실행이 됨
SELECT * FROM EMP WHERE EXISTS (SELECT * FROM DEPT WHERE DEPTNO = 10);
SELECT * FROM EMP;
SELECT DNAME FROM DEPT WHERE DEPTNO = 100; -- 결과가 존재하지 않기 때문에 FALSE
-- EXISTS 연산자에서 FALSE로 사용이 되면 앞에 SQL 문이 정상적으로 실행이 되지 않음 = 데이터 출력 없음
SELECT * FROM EMP WHERE EXISTS (SELECT DNAME FROM DEPT WHERE DEPTNO = 100);
-- 다중열 서브쿼리 = 열이 여러 개 = 복수열 서브쿼리
SELECT DEPTNO, MIN(SAL) FROM EMP GROUP BY DEPTNO;
SELECT * FROM EMP WHERE (DEPTNO, SAL) IN (SELECT DEPTNO, MIN(SAL) FROM EMP GROUP BY DEPTNO);
SELECT DEPTNO, MAX(SAL) FROM EMP GROUP BY DEPTNO;
SELECT * FROM EMP WHERE (DEPTNO, SAL) IN (SELECT DEPTNO, MAX(SAL) FROM EMP GROUP BY DEPTNO);
-- FROM 절 뒤에 사용하는 서브쿼리
-- 인라인 뷰 = SQL문 실행 결과를 마치 테이블처럼 사용
SELECT * FROM EMP WHERE DEPTNO = 30;
SELECT * FROM DEPT;
SELECT E30.EMPNO, E30.ENAME, D.DEPTNO,D.DNAME
FROM (SELECT * FROM EMP WHERE DEPTNO = 30) E30
, (SELECT * FROM DEPT) D
WHERE E30.DEPTNO = D.deptno;
-- 인라인 뷰에 사용하는 SQL문이 길어진다면 WITH 절 사용하면 됨
-- 가독성을 높이기 위한 목적
-- WITH 절에서 미리 내용을 파악할 수 있음 => SELECT 문을 읽으먼 도움이 됨
WITH E30 AS (SELECT * FROM EMP WHERE DEPTNO = 30)
, D AS (SELECT * FROM DEPT)
SELECT E30.EMPNO, E30.ENAME, D.DEPTNO, D.DNAME
FROM E30, D
WHERE E30.DEPTNO = D.DEPTNO;
-- SELECT 절 뒤에서 사용하는 서브쿼리 = 스칼라 서브쿼리 = 열처럼 사용
SELECT DNAME FROM EMP A, DEPT B WHERE A.DEPTNO = B.DEPTNO;
SELECT GRADE FROM EMP C, SALGRADE D WHERE C.SAL BETWEEN D.LOSAL AND D.HISAL;
SELECT EMPNO, ENAME, JOB, SAL,
(SELECT GRADE FROM SALGRADE WHERE A.SAL BETWEEN LOSAL AND HISAL) AS GRADE,
DEPTNO,
(SELECT DNAME FROM DEPT B WHERE A.DEPTNO = B.DEPTNO) AS DNAME
FROM EMP A;
--
-- 데이터 조작어 DML, Data Manipulation Language
-- 데이터 수정하는 SQL 문장
-- TCL을 함께 사용해야 함(신중하게) - 최종변경 / 취소
-- 데이터 정의어 DDL, Data Definition Language + 자동 COMMIT
-- 원본을 복사한 실습용 테이블 만들기
CREATE TABLE DEPT_COPY
AS SELECT * FROM DEPT;
SELECT * FROM DEPT_COPY;
-- 테이블 삭제
DROP TABLE DEPT_COPY;
-- 데이터 추가 INSERT
-- INSERT INTO 테이블 이름(열이름) VALUES (값)
INSERT INTO DEPT_COPY(DEPTNO, DNAME, LOC) VALUES (50, 'DA', 'BUSAN');
SELECT * FROM DEPT_COPY;
ROLLBACK;
-- 전체 열에 추가하는 경우는 열 생략
INSERT INTO DEPT_COPY VALUES (50, 'DA', 'BUSAN');
SELECT * FROM DEPT_COPY;
-- 데이터 타입 확인
DESC DEPT_COPY;
-- INSERT 문의 오류 발생의 경우
-- 1) 열 개수와 값 개수의 불일치
SELECT * FROM DEPT_COPY;
-- 열 3개 값 2개 생긴 오류 = 3번째 값을 같이 넣으면 해결
INSERT INTO DEPT_COPY (DEPTNO, DNAME, LOC) VALUES (60, 'DS');
INSERT INTO DEPT_COPY (DEPTNO, DNAME, LOC) VALUES (60, 'DS', 'SEOUL');
SELECT * FROM DEPT_COPY;
ROLLBACK;
SELECT * FROM DEPT_COPY;
-- 열을 2개로 넣어 삽입 -> 나머지 하나는 null값
INSERT INTO DEPT_COPY (DEPTNO, DNAME) VALUES (60, 'DS');
SELECT * FROM DEPT_COPY;
-- 2) 데이터 타입의 불일치
-- 숫자를 넣어야 하는 열에 문자를 넣었기 때문에 발생한 오류
INSERT INTO DEPT_COPY (DEPTNO, DNAME, LOC) VALUES ('70번', 'DE', 'SUWON');
INSERT INTO DEPT_COPY (DEPTNO, DNAME, LOC) VALUES (70, 'DE', 'SUWON');
SELECT * FROM DEPT_COPY;
-- 3) 데이터 입력 범위 벗어남
-- 2자리 숫자에 3자리 숫자를 넣어서 발생한 오류
INSERT INTO DEPT_COPY (DEPTNO, DNAME, LOC) VALUES (100, 'DE', 'INCHEON');
INSERT INTO DEPT_COPY (DEPTNO, DNAME, LOC) VALUES (80, 'DE', 'INCHEON');
SELECT * FROM DEPT_COPY;
-- NULL 데이터 추가
SELECT * FROM DEPT_COPY;
ROLLBACK;
-- 명시적 입력
INSERT INTO DEPT_COPY(DEPTNO, DNAME, LOC) VALUES (50, 'DA', NULL);
SELECT * FROM DEPT_COPY;
-- 암시적 입력
INSERT INTO DEPT_COPY (DEPTNO, DNAME) VALUES (60, 'DS');
SELECT * FROM DEPT_COPY;
-- BLANK 데이터 추가
INSERT INTO DEPT_COPY (DEPTNO, DNAME, LOC) VALUES (70, 'DE', '');
SELECT * FROM DEPT_COPY;
-- 개발자와 협력할 때는 비어있는 값이라는 의미를 확실히 전달하기 위해서는 NULL 용어 사용 권장
-- 날짜 데이터 INSERT
-- 실습 테이블 EMP 테이블이 가지고 있는 구조만 복사 = 열만 복사 = 행은 복사하지 않음
CREATE TABLE EMP_COPY
AS SELECT * FROM EMP WHERE 1 != 1;
SELECT * FROM EMP_COPY;
-- 팀장 2명 추가
INSERT INTO EMP_COPY (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
VALUES (5555, '장원영', 'MANAGER', 7839 '2023/05/22', 4000, 0, 10);
SELECT * FROM EMP_COPY;
INSERT INTO EMP_COPY (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
VALUES (7777, '차은우', 'MANAGER', 7839 '2023-05-22', 4000, 0, 10);
SELECT * FROM EMP_COPY;
-- 날짜 형식을 다르게 = 일/월/연
INSERT INTO EMP_COPY (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
VALUES (8888, '김민종', 'MANAGER', 7839, TO_DATE('22/05/2023', 'DD/MM/YYYY'), 4000, 0, 10);
SELECT * FROM EMP_COPY;
-- 현재 날짜로 입력
INSERT INTO EMP_COPY (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
VALUES (9999, 'q배성욱', 'ANALYST', 5555, SYSDATE, 4000, NULL, 10);
SELECT * FROM EMP_COPY;
-- 서브쿼리로 추가
SELECT * FROM EMP_COPY;
SELECT A.EMPNO, A.ENAME, A.JOB, A.MGR, A.HIREDATE, A.SAL, A.COMM, A.DEPTNO
FROM EMP A, SALGRADE B
WHERE A.SAL BETWEEN B.LOSAL AND B.HISAL
AND B.GRADE = 2;
INSERT INTO EMP_COPY (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
SELECT A.EMPNO, A.ENAME, A.JOB, A.MGR, A.HIREDATE, A.SAL, A.COMM, A.DEPTNO
FROM EMP A, SALGRADE B
WHERE A.SAL BETWEEN B.LOSAL AND B.HISAL
AND B.GRADE = 2;
SELECT * FROM EMP_COPY;
-- 데이터 변경 UPDATE
SELECT * FROM DEPT_COPY;
DROP TABLE DEPT_COPY;
CREATE TABLE DEPT_COPY
AS SELECT * FROM DEPT;
-- 전체 = 일괄적으로 변경
UPDATE DEPT_COPY
SET LOC = 'JEJU'
SELECT * FROM DEPT_COPY;
-- 취소
ROLLBACK;
SELECT * FORM DEPT_COPY;
-- 30번 부서 이름과 위치 변경
SELECT * FROM DEPT_COPY WHERE DEPTNO = 30;
SELECT DNAME, LOC FROM DEPT_COPY WHERE DEPTNO = 30;
UPDATE DEPT_COPY
SET DNAME = 'DA',
LOC = 'SEOUL'
WHERE DEPTNO = 30;
SELECT * FROM DEPT_COPY;
-- 수당 변경
SELECT * FROM EMP_COPY WHERE EMPNO = 9999;
UPDATE EMP_COPY
SET COMM = 1000
WHERE EMPNO = =9999;
SELECT * FROM EMP_COPY WHERE EMPNO = 9999;
-- 서브쿼리 이용하여 변경
SELECT * FROM DEPT_COPY;
SELECT DANME, LOC FROM DEPT WHERE DEPTNO = 30;
-- DA SEOUL => SALES CHICAGO 변경
UPDATE DEPT_COPY
SET (DNAME, LOC) = (SELECT DANME, LOC FROM DEPT WHERE DEPTNO = 30)
WHERE DEPTNO = 30;
-- 서브쿼리를 조건절에 사용
SELECT * FROM DEPT_COPY WHERE DNAME = 'RESEARCH';
-- DALLAS - BUSAN로변경
-- 데이터 삭제 DELETE
DELETE EMP_COPY WHERE JOB = 'CLERK'
SELECT * FROM EMP_COPY WHERE JOB = 'CLERK'
-- 서브쿼리를 이용하여 데이터 일부 삭제
SELECT * FROM EMP_COPY;
SELECT * FROM SALGRADE;
SELECT A.EMPNO FROM EMP_COPY A, SALGRADE B
WHERE A.SAL BETWEEN B.LOSAL AND B.HISAL
AND B.GRADE = 2;
SELECT * FROM EMP_COPY WHERE EMPNO IN (SELECT A.EMPNO FROM EMP_COPY A, SALGRADE B
WHERE A.SAL BETWEEN B.LOSAL AND B.HISAL
AND B.GRADE = 2);
DELETE EMP_COPY WHERE EMPNO IN (SELECT A.EMPNO FROM EMP_COPY A, SALGRADE B
WHERE A.SAL BETWEEN B.LOSAL AND B.HISAL
AND B.GRADE = 2);
-- 테이블 삭제 = 데이터 전체 삭제
SELECT * FROM EMP_COPY;
DELETE EMP_COPY
SELECT * FROM EMP_COPY;
-- 테이블 행 + 열 = 테이블 삭제
SELECT * FROM DEPT_COPY;
DROP TABLE DEPT_COPY;
-- 트랜잭션 제어 TCL, Transaction Control Language
-- COMMIT : 최종 변경
-- ROLLBACK : 취소
-- 실습 테이블 생성
CREATE TABLE DEPT_COPY
AS SELECT * FROM DEPT;
SELECT * FROM DEPT_COPY;
-- 3가지 DML 실행 후 취소
INSERT INTO DEPT_COPY VALUES (50, 'DA', 'SEOUL');
SELECT * FROM DEPT_COPY;
UPDATE DEPT_COPY
SET LOC = 'SUWON'
WHERE DEPTNO = 50;
SELECT * FROM DEPT_COPY;
DELETE DEPT_COPY WHERE DNAME = 'ACCOUNTING';
SELECT * FROM DEPT_COPY;
ROLLBACK;
-- 3가지 DML 실행 후 최종 변경
INSERT INTO DEPT_COPY VALUES (50, 'DA', 'SEOUL');
SELECT * FROM DEPT_COPY;
UPDATE DEPT_COPY
SET LOC = 'SUWON'
WHERE DEPTNO = 50;
SELECT * FROM DEPT_COPY;
DELETE DEPT_COPY WHERE DNAME = 'ACCOUNTING';
SELECT * FROM DEPT_COPY;
COMMIT;
SELECT * FROM DEPT_COPY;
-- 읽기 일관성
-- 편집은 sqldeveloper에서 하고 붙여넣기를 sqlplus에 할 것
-- sqldeveloper, sqlplus 각자 실행
SELECT * FROM DEPT_COPY;
-- 현재 양쪽에 보여지는 결과는 동일
-- sqldeveloper에서 데이터 삭제
DELETE DEPT_COPY WHERE DEPTNO = 50;
-- sqldeveloper, sqlplus 각자 실행
SELECT * FROM DEPT_COPY;
-- sqldeveloper에서 최종 변경
COMMIT;
-- sqldeveloper, sqlplus 각자 실행
SELECT * FROM DEPT_COPY;
-- sqldeveloper에서 데이터 변경
-- sqldeveloper, sqlplus 각자 실행
UPDATE DEPT_COPY
SET DNAME = 'DA'
WHERE DEPTNO = 30;
-- sqldeveloper에서 최종 변경
COMMIT;
--
-- 데이터 정의어 DDL, Data Definition Language = 자동 COMMIT
-- 테이블 생성
-- 1) 열 이름과 자료형을 정의하면서 테이블 생성
SELECT * FROM EMP_COPY;
DROP TABLE EMP_COPY;
SELECT * FROM EMP_COPY;
-- EMP_COPY 테이블 만들기
SELECT * FROM EMP;
CREATE TABKE EMP_COPY(
EMPNO NUMBER(4),
ENAME VARCHAR2(10),
JOB VARCHAR2(9),
MGR NUMBER(4),
HIREDATE DATE,
SAL NUMBER(7, 2),
COMM NUMBER(7, 2),
DEPTNO NUMBER(2)
);
--
-- 2) 전체 행과 열을 복사하여 테이블 생성 = 열 구조 + 데이터
SELECT * FROM DEPT_COPY;
DROP TABLE DEPT_COPY;
CREATE TABLE DEPT_COPY
AS SELECT * FROM DEPT;
SELECT * FROM DEPT_COPY;
-- 3) 일부 행과 열을 복사하여 테이블 생성 = 열 구조 + 일부 데이터
CREATE TABLE DEPT_COPY_30
AS SELECT * FROM DEPT WHERE DEPTNO = 30;
SELECT * FROM DEPT_COPY_30;
-- 4) 열을 복사하여 테이블 생성 = 열 구조 = 행이 없음
SELECT A.EMPNO, A.ENAME, A.HIREDATE, A.SAL,
B.DEPTNO, B.DNAME
FROM EMP A, DEPT B WHERE A.DEPTNO = B.DEPTNO;
SELECT A.EMPNO, A.ENAME, A.HIREDATE, A.SAL,
B.DEPTNO, B.DNAME
FROM EMP A, DEPT B
WHERE 1 != 1;
CREATE TABLE EMP_DEPT
AS SELECT A.EMPNO, A.ENAME, A.HIREDATE, A.SAL, B.DEPTNO, B.DNAME
FROM EMP A, DEPT B
WHERE 1 != 1;
SELECT * FROM EMP_DEPT;
-- 테이블 변경
CREATE TABLE EMP_ALTER
AS SELECT * FROM EMP;
SELECT * FROM EMP_ALTER;
-- 1) 열 추가
ALTER TABLE EMP_ALTER
ADD PHONE VARCHAR2(15);
SELECT * FROM EMP_ALTER;
-- 2) 열 이름 변경 = RENAME 변경 전 이름 TO 변경 후 이름
ALTER TABLE EMP_ALTER
RENAME COLUMN PHONE TO CP;
SELECT * FROM EMP_ALTER;
-- 3) 열의 데이터 타입 변경
DESC EMP_ALTER;
ALTER TABLE EMP_ALTER
MODIFY EMPNO NUMBER(5);
DESC EMP_ALTER;
-- 4) 열 삭제
ALTER TABLE EMP_ALTER
DROP COLUMN CP;
SELECT * FROM EMP_ALTER;
-- 테이블 이름 변경
RENAME EMP_ALTER TO EMP_ALTER_AFTER;
DESC EMP_ALTER;
SELECT * FROM EMP_ALTER;
DESC EMP_ALTER_AFTER;
SELECT * FROM EMP_ALTER_AFTER;
-- 데이터 삭제 = 테이블 비우기 = 열 구조는 남아 있고 행이 모두 삭제
TRUNCATE TABLE EMP_ALTER_AFTER;
SELECT * FROM EMP_ALTER_AFTER;
-- 테이블 삭제
DROP TABLE EMP_ALTER_AFTER;
SELECT * FROM EMP_ALTER_AFTER;
```