개발 공부/SQL

SUBQUERY / DDL/ DML

공부하는개발자_ 2023. 6. 16. 17:28

위치에 따라

Subquery : WHERE절
subquery의 결과를 조건에 활용하는 방식으로 사용. 

WHERE 필드명 IN (SUBQUERY)

 

InlineVies : FROM절

ScalarQuery : SELECT

 

실행결과 행수에 따라

단일행 서브쿼리 : 메인쿼리와 일반비교연산 ( =, >, <, >=, <=, <> )

여러행 서브쿼리 : 메인쿼리와 특수비교연산 (IN, ANY, ALL)

 

사원의 최대 급여를 출력하시오

SELECT MAX(salary)

FROM employees;

 

 

사원의 최대 급여자의 사번, 이름, 급여를 출력하시오

1) 사원의 최대 급여를 계산한다

2) 1)과 같은 급여갖는 사원 검색, 출력

SELECT employee_id, first_name, salary

FROM employees

WHERE salary = (SELECT MAX(salary))

                             FROM employees

                            );

 

 

성(last_name)이 'Davies'인 사원과 같은 부서에 근무하는 사원들의 사번, 성, 이름을 출력하시오 --44건

1)  성(last_name)이 'Davies'의 부서번호를 검색한다

2) 1)과 같은 부서번호를 갖는 사원 검색, 출력

--Davies는 제외하고 출력한다. 

SELECT employee_id, last_name, first_name

FROM employees

WHERE department_id = (SELECT department_id

                                           FROM employees

                                           WHERE last_name = 'Davies')

AND last_name <> 'Davies' ;

 

 

여러행 서브쿼리

부서별 최대 급여를출력하시오 --12건

SELECT department_id, MAX(salary)

FROM employees

GROUP BY department_id;

 

 

부서별 최대급여자의 사번, 이름, 급여를 출력하시오

1) 부서별 최대급여 계산

2) 1)과 같은 급여를 갖는 사원 검색, 출력

SELECT employee_id, first_name, salary

FROM employees

WHERE salary IN (SELECT MAX(salary)

                           FROM employees

                           GROUP BY department_id

                           ); --24건(x)

 

 

SELECT employee_id, first_name, salary

FROM employees

WHERE (department_id, salary) IN (SELECT department_id, MAX(salary)

                                                          FROM employees

                                                          GROUP BY department_id

                                                          ); --11건(부서없는 사원은 제)

 

 

=>WHERE (department_id, salary) IN (SELECT department_id, MAX(salary)

    쌍을 맞춰줘야함.

 

 

SELECT department_id, employee_id, first_name, salary

FROM employees

WHERE (NVL(department_id, 0), salary) IN (SELECT NVL(department_id, 0), MAX(salary)

                                                                      FROM employees

                                                                      GROUP BY department_id

                                                                       ); -- 12건(부서없는 사원도 출력)

 

 

 

부서별 최대 급여자를 제외한 사원의 부서번호, 사번, 이름, 급여를 출력하시오

1) 부서별 최대급여자의 부서번호, 최대급여 계산

2) 1)과 다른 부서번호, 급여를 갖는 사원을 검색, 출력한다

 

 

= ANY는 IN과 같음, >ANY : 최소값보다 크다, <ANY : 최대값보다 작다

= ALL : 결과없음 , >ALL : 최대값 보다 크다 , <ALL : 최소값보다 작다

SELECT department_id, employee_id, first_name, salary

FROM employees

WHERE (NVL(department_id, 0), salary) =ANY (SELECT NVL(department_id, 0), MAX(salary)

                                                                      FROM employees

                                                                      GROUP BY department_id

                                                                       ); -- 12건(부서없는 사원도 출력)

 

 

InlineView

행번호(rownum)는 1부터 시작한다, 조건에 만족하는 행을 만나면 rownum이 1씩 증가한다

 

SELECT 처리순서 : FROM -> WHERE-> GROUP BY-> HAVING -> SELECT -> ORDER BY

 

사원의 행번호, 사번, 급여를 출력하시오

SELECT rownum, employee_id, salary

FROM employees;

 

입사일자가 '07/01/01' 이후 입사한 사원의 행번호, 사번, 입사일자, 급여를 출력하시오

SELECT rownum, employee_id, hire_date, salary

FROM employees

WHERE hire_date >= '07/01/01' ;

 

입사일자가 '07/01/01' 이후 입사한 사원의 행번호, 사번, 입사일자, 급여를 출력하시오

적은 급여부터자 부터 출력한다

SELECT rownum, employee_id, hire_date, salary

FROM employees

WHERE hire_date >= '07/01/01' 

ORDER BY salary;

 

=> SELECT rownum 처리 후 ORDER BY salary 순서로 처리되었기 때문에 ROWNUM순차는 뒤섞이게 됨.

 

SELECT rownum, employee_id, hire_date, salary

FROM (

            SELECT rownum, employee_id, hire_date, salary

            FROM employees

            WHERE hire_date >= '07/01/01' 

            ORDER BY salary

);

 

 

 

입사일자가 '07/01/01' 이후 입사한 사원의 행번호, 사번, 입사일자, 급여를 출력하시오

적은 급여부터자 부터 출력한다

SELECT rownum, employee_id, hire_date, salary

FROM (

            SELECT rownum, employee_id, hire_date, salary

            FROM employees

            WHERE hire_date >= '07/01/01' 

            ORDER BY salary

)

WHERE rownum < = 5 ; 

 

 

입사일자가 '07/01/01' 이후 입사한 사원의 행번호, 사번, 입사일자, 급여를 출력하시오

적은급여자부터 6행부터 10행만 출력한다

SELECT rownum, employee_id, hire_date, salary

FROM (

            SELECT rownum, employee_id, hire_date, salary

            FROM employees

            WHERE hire_date >= '07/01/01' 

            ORDER BY salary

)

WHERE rownum BETWEEN 6 AND 10; (X)

=> WHERE rownum BETWEEN 6 AND 10; -- WHERE절 초기값은 1인데 6AND10 조건에 맞지 않아

결과 값이 나오지 않음

 

 

SELECT * -- ( = rn, employee_id 사번, )

FROM (SELECT rownum rn, a.*

            FROM (

                        SELECT employee_id, hire_date, salary

                        FROM employees

                        WHERE hire_date >= '07/01/01' 

                        ORDER BY salary

             ) a

)

WHERE rn BETWEEN 6 AND 10; 

 

5. Scalar Subquery

사원의 사번, 이름, 부서번호, 부서명을 출력하시오

SELECT employee_id, first_name, d.department_id, department_name

FROM employee e JOIN departments d ON (e.department_id = d.department_id) ;

 

SELECT employee_id, first_name, department_id,

              (SELECT department_name

               FROM departments

               WHERE department_id = employees.department_id)

FROM employees ; 

 

사원의 부서별 부서번호, 부서명, 총급여를 출력하시오. 부서 없는 사원도 출력한다

SELECT e.department_id, department_name, SUM(salary)

FROM employees e LEFT JOIN departments d ON (e.department_id = d.department_id)

GROUP BY e.department_id, department_name;

 

SELECT department_id, 

              (SELECT department_name

               FROM departments

               WHERE department_id = employees.department_id),

               SUM(salary)

FROM employees

GROUP BY department_id;

-----------------------------------------------------------------

'Sales' 부서번호: 80번

SELECT * FROM departments WHERE department_name = 'Sales';

Sales 평균급여: 8955.8823~
SELECT AVG(salary) FROM employees WHERE department_id = 80;

 

sales평균급여보다 많은 급여자

SELECT employee_id, department_id, salary

FROM employees

WHERE department_id =80 AND salary > 8955.8823~

 

sales평균급여보다 많은  sales부서의 급여자

 

Sales 부서의 평균급여를 출력하시오

SELECT AVG(salary)
FROM employees

WHERE department_id =

(SELECT department_id FROM departments WHERE department_name = 'Sales');

 

 

SELECT e.department_id, department_name, AVG(salary) FROM employees e JOIN departments d ON (e.department_id = d.department_id) WHERE department_name = 'Sales' 

 

 

Sales 부서의 평균급여보다 많은 급여를 받는 사원의 부서번호, 급여를 출력하시오

SELECT employee_id, department_id, salary

FROM employees

WHERE salary > (SELECT AVG (salary)

                           FROM employees

                           WHERE department_id = (SELECT department_id

                                                                     FROM departments

                                                                      WHERE department_name = 'Sales')

                             );

 

Sales 부서의 평균급여보다 많은 급여를 받는 'Sales'부서사원의 부서번호, 급여를 출력하시오 -- subquery편리

SELECT employee_id, department_id, salary

FROM employees

WHERE department_id =  (SELECT department_id

                                                                      FROM departments

                                                                      WHERE department_name = 'Sales')

AND         salary > (SELECT AVG (salary)

                               FROM employees

                               WHERE department_id = (SELECT department_id

                                                                          FROM departments

                                                                          WHERE department_name = 'Sales')

                             );

 

 

 

상호 연관 서브쿼리로 해결

SELECT employee_id, department_id, salary

FROM employees e

WHERE department_id =  (SELECT department_id

                                                                      FROM departments

                                                                      WHERE department_name = 'Sales')

AND         salary > (SELECT AVG (salary)

                               FROM employees

                               WHERE department_id = e.department_id) ;

 

DDL (데이터 정의어) - 객체를 생성: CREATE , 구조변경:ALTER, 제거:DROP
CREATE 객체종류
CREATE TABLE
ex) CREATE TABLE, CREATE VIEW, CREATE SEQUENCE

1. 테이블 생성
CREATE TABLE product(
 prod_no VARCHAR2(5), 
 prod_name VARCHAR2(20)  
); 

테이블구조확인
DESC product

2. 테이블구조 변경
ALTER TABLE product 
ADD prod_price NUMBER(1)     -- 컬럼추가


2) 컬럼 이름 변경

ALTER TABLE product
ADD a NUMBER(1);

 

3) 컬럼의 자료형 또는 자릿수 변경
ALTER TABLE product
MODIFY prod_price NUMBER(6);

 

ALTER TABLE product
MODIFY prod_price DEFAULT 0;

 

4) 컬럼 삭제

ALTER TABLE product

DROP COLUMN abc;

 

5) 제약조건 추가

(테이블레벨로 추가)

ALTER TABLE product

ADD CONSTRAINTS prod_no_pk PRIMARY KEY(prod_no);

 

(컬럼 레벨로 추가)

ALTER TABLE product
MODIFY prod_name CONSTRAINTS prod_name_nn NOT NULL;

 

3. 테이블 제거

DROP TABLE product;

 

 

무결성 제약조건

설정방법: 테이블레벨로 설정, 컬럼레벨로 설정하는 방법이 있다

그 중 NOT NULL제약 조건은 컬럼 레벨로만 설정 할 수 있다

(1)테이블 레벨로 설정

    CREATE TABLE t_a(c_a number (5) default 0, 

                                      c_b varchar2(10),

                                      constraint c_a_pk PRIMARY KEY(c_a),

                                      constraint c_b_ck CHECK (c_b IN ('남', '여'))

     )

 

(2) 컬럼레벨로 설정

CREATE TABLE t_a(c_a number(5) default 0 constraint c_a_pk PRIMARY KEY,

c_b varchar2(10) constraint c_b_ck CHECK (c_b IN ('남', '여')) 

NOT NULL

 

1. NOT NULL : 컬럼레벨로만 설정 가능

2. UNIQUE

3. PRIMARY KEY : NOT NULL + UNIQUE

4. CHECK

5. FOREIGN KEY


DML(데이터 조작어) - 추가 INSERT, 수정 UPDATE, 삭제DELETE

 

SELECT * FROM product;

1. 데이터추가

INSERT INTO product(prod_no, prod_name) VALUES ('C0001', '아메리카노' );

INSERT INTO product(prod_no, prod_name) VALUES ('C0002', '라떼' );

INSERT INTO product(prod_no, prod_name) VALUES ('C0003', '핫초코' );

 

ALTER TABLE product
MODIFY prod_name VARCHAR2(100);

 

INSERT INTO product(prod_no, prod_name) VALUES ('C0004', '아이스딸기아사이' );

 

INSERT INTO product VALUES ('F0001', '치즈케이크', 1000);

INSERT INTO product VALUES ('F0002', '치즈베이글', NULL);

INSERT INTO product VALUES ('F0003', '치킨샌드위치', ' ');

INSERT INTO product VALUES ('F0004', '밀박스'); --상품가격 입력필수

 

INSERT INTO product  VALUES (C0001', '다른상품', 0); --상품번호중복 - PK제약조건에 위배

INSERT INTO product  VALUES (' ', '번호가없는상품1', 0); --상품번호NULL - PK제약조건에 위배

INSERT INTO product  VALUES (' ', '번호가없는상품2', 0);

 

DELETE product WHERE prod_name = '다른상품';

DELETE product WHERE prod_no IS NULL;

 

INSERT INTO product(prod_no, prod_name) VALUES ('D0001', '라임블렌디드'); --OK

INSERT INTO product(prod_no, prod_name) VALUES ('D0002', NULL); --OK

DELETE product WHERE prod_name IS NULL;

 

 

 

UPDATE product SET prod_name= prod_name || '음료' , = prod_price=3000 WHERE prod_no LIKE 'D%' ;  

'개발 공부 > SQL' 카테고리의 다른 글

COMMIT / ROLLBACK  (2) 2023.06.20
제약 조건 / ERD 사용  (1) 2023.06.20
GROUP BY / HAVING/ JOIN/ UNION  (0) 2023.06.15
SQL 함수  (1) 2023.06.14
SQL Developer : SELECT  (2) 2023.06.13