Database
서브쿼리
서브쿼리의 종류
- 스칼라 서브쿼리
- 하나의 행에서 하나의 값만 반환하는 서브쿼리다.
- 스칼라 서브쿼리는 select절, insert문의 values에서 사용할 수 있다.
- 스칼라 서브쿼리는 decode 및, case의 조건 및 표현식에서 사용할 수 있다.
select col1, col2, (select col3 from table2 where 조건식)
from table1;
insert into table1
(col1, col2, col3, ...)
values
(값, 값, (select col4 from table2 where 조건식));
SELECT O.employee_id, O.first_name, O.salary,
(SELECT TRUNC(AVG(I.salary)) FROM employees I) avg_salary
FROM employees O;
UPDATE employees
SET
salary = salary + (SELECT TRUNC(AVG(salary)*0.1) FROM employees);
INSERT INTO employees
(employee_id, first_name, last_name, email, phone_number, hire_date, job_id, salary, commission_pct, manager_id, department_id)
VALUES
(employees_seq.nextval, 'Gildong', 'Hong', 'GILDONG', '010.1111.2222', sysdate, 'IT_PROG',(SELECT min_salary FROM jobs WHERE job_id = 'IT_PROG') ,null, 103, 60);
데이터 정의어(DDL)
- 오라클 데이터베이스 객체 생성, 변경, 삭제에 사용되는 명령어
- CREATE, ALTER, DROP, TRUNCATE
뷰
- 테이블 혹은 다른 뷰를 기반으로 하는 가상의 테이블(논리적인 테이블)이다.
- 특징
- 물리적인 저장공간을 가지지 않는다.
- INSERT, UPDATE, DETELE 작업의 수행이 불편하다.
- 목적
- 복잡한 SQL문을 간단하게 작성하기 위해서 사용
- 데이터의 엑세스를 제한하기 위해서 사용(데이터에 대한 보안성 강화)
- 동일한 데이터로부터 다양한 결과를 얻기 위해서 사용
- 종류
- 단순 뷰
- 한 테이블에서만 데이터를 가져온다.
- 함수 또는 데이터 그룹을 사용하지 않았음
- DML(INSERT/UPDATE/DELETE가 가능은 하다)
- 복합 뷰
- 여러 테이블에 데이터를 가져온다.
- 함수 또는 데이터 그룹을 포함하고 있음
- DML 거의 불가능하다.
- 뷰 생성
CREATE [OR REPLACE] VIEW 뷰이름
AS 서브쿼리
WITH READ ONLY
CREATE OR REPLACE VIEW 뷰이름
AS 서브쿼리
DROP VIEW 뷰이름
인라인 뷰
- SELECT 문의 FROM절에 서브쿼리를 정의하고, 이 서브쿼리로 조회된 결과를 가상의 테이블로 취급하고, 별칭을 부여한 것
- 데이터베이스 객체가 아니다.
- 형식
SELECT A.column, A.column, A.column
FROM (SELECT column, column, column, ...
FROM table1
WHERE 조건식) A
WHERE 조건식
CREATE OR REPLACE VIEW departments_detail_view
AS
SELECT D.department_id, D.department_name, D.manager_id, E.first_name, E.last_name, L.city, l.street_address,
(SELECT COUNT(*) FROM employees I WHERE I.department_id = D.department_id) emp_cnt
FROM departments D, employees E, locations L
WHERE D.manager_id = E.employee_id(+)
AND D.location_id = L.location_id;
SELECT department_id, department_name, manager_id, first_name, last_name, city, street_address, emp_cnt
FROM departments_detail_view
WHERE department_id = 60;
CREATE OR REPLACE VIEW employees_detail_view
AS
SELECT E.employee_id emp_id, E.first_name || ',' || E.last_name as full_name, E.email, E.phone_number,
E.hire_date, TRUNC(MONTHS_BETWEEN(SYSDATE, E.hire_date)) work_monhs,
TRUNC(MONTHS_BETWEEN(SYSDATE, E.hire_date) / 12) working_year, E.salary, E.commission_pct, G.grade,
E.salary*12+E.salary*12*nvl(E.commission_pct, 0) annual_salary, M.employee_id as manager_id,
M.first_name || ',' || M.last_name as manager_name, E.job_id, J.job_title, D.department_id, D.department_name,
DM.employee_id dept_manager_id,
DM.first_name || ',' || DM.last_name as department_manger_name
FROM employees E, salary_grade G, employees M, jobs J, departments D, employees DM
WHERE E.salary >= G.min_salary and E.salary <= G.max_salary
AND E.manager_id = M.employee_id(+)
AND E.job_id = J.job_id
AND E.department_id = D.department_id
AND D.manager_id = DM.employee_id(+) with read only;
SELECT emp_id, full_name, salary, grade, annual_salary, job_id, department_name
FROM EMPLOYEES_DETAIL_VIEW
WHERE emp_id = 200;
SELECT grade, count(*)
FROM EMPLOYEES_DETAIL_VIEW
GROUP BY grade
ORDER BY grade;
SELECT emp_id, full_name, hire_date, working_year
FROM employees_detail_view
WHERE working_year >= 15
ORDER BY working_year DESC;
SELECT emp_id, full_name, salary, grade, annual_salary, job_id
FROM EMPLOYEES_DETAIL_VIEW
WHERE annual_salary >= 200000;
SELECT A.job_id, B.job_title, B.min_salary, B.max_salary, A.cnt
FROM (SELECT job_id, count(*) cnt
FROM EMPLOYEES
GROUP BY job_id) A, jobs B
WHERE A.job_id = B.job_id;
SELECT rownum, emp_id, full_name, annual_salary
FROM (SELECT emp_id, full_name, annual_salary
FROM employees_detail_view
ORDER BY annual_salary desc)
WHERE rownum <=10;
SELECT rownum, job_id, cnt
FROM (SELECT job_id, COUNT(*) cnt
FROM employees
GROUP BY job_id
ORDER BY cnt desc)
WHERE rownum <= 3;
SELECT ranking, job_id, cnt
FROM (SELECT rownum ranking, job_id, cnt
FROM (SELECT job_id, COUNT(*) cnt
FROM employees
GROUP BY job_id
ORDER BY cnt desc))
WHERE ranking >= 6 and ranking <= 10;