티스토리 뷰
서브쿼리
안녕하세요 강정호입니다. 오늘은 서브쿼리에 대해 실습 위주로 알아보겠습니다.
주요 용어 설명은 잘 정리되어 있는 링크로 대신 하고 오늘은 주로 쿼리문 위주로 공부해 볼게요!
1. NULL을 포함하는 쿼리문
SELECT Fname, Lname FROM EMPLOYEE WHERE Super_ssn IS NULL;
- EMPLOYEE 테이블에서 Super_ssn이 NULL인 직원의 Fname, Lname 값을 구하여라.
결과는 다음과 같이 나왔습니다.
2. 서브쿼리문(Nested Query)
서브쿼리란? 서브쿼리 정의
- 서브쿼리가 다 같은 서브쿼리로 알고 있었으나 쿼리가 위치한 곳에 따라 다르게 불리어진다. SELECT 문 뒤(스칼라 쿼리문), FROM 절 뒤(인라인 뷰), WHERE 절 뒤(서브쿼리) 라는 각각의 명칭이 있다.
SQL IN 연산자란?
- SQL IN 연산자 : IN 연산자
- SQL IN 연산자 실습 : IN 연산자 실습
요약해서 말하자면 IN 연산자는 Where 뒤에 여러 개의 조건문이 OR로 나열된 것과 같다.
위와 같이 IN을 사용하여 Germany, France, UK의 값만 추출하였다.
IN 연산자를 사용한 서브 쿼리문
1 2 3 4 5 6 7 8 9 10 11 | SELECT DISTINCT Pnumber FROM PROJECT WHERE Pnumber IN (SELECT Pnumber FROM PROJECT, DEPARTMENT, EMPLOYEE WHERE Dnum = Dnumber AND Mgr_ssn = Ssn AND Lname = 'Smith') OR Pnumber IN (SELECT Pno FROM WORKS_ON, EMPLOYEE WHERE Essn = Ssn AND Lname = 'Smith'); | cs |
이 쿼리문은 Pnumber(프로젝트 번호)를 구하는 쿼리문이다. Pnumber를 2개의 서브쿼리문에서 가져온다. 첫 번째 서브쿼리문은 PROJECT, DEPARTMENT, EMPLOYEE를 Inner Join 하여 가져온다. 두 번째 서브쿼리문은 WORKS_ON, EMPLOYEE 테이블을 Inner Join 하여 가져온다.
2개의 서브쿼리문에서 나온 Pnumber에 해당하는 데이터를 PROJECT 테이블에서 추출한다.
Tuple의 값을 이용한 IN 서브쿼리문
1 2 3 4 5 | SELECT DISTINCT Essn FROM WORKS_ON WHERE (Pno, Hours) IN (SELECT Pno, Hours FROM WORKS_ON WHERE Essn = '123456789'); | cs |
WORKS_ON 테이블에서 중복되지 않는 Essn을 가져온다. 어떤 Essn을 가져오냐 하면 WORKS_ON 테이블에서 Pno, Hours가 Essn = '123456789' 에 해당하는 것만 가져온다.
서브쿼리에서 이미 Essn = '123456789'에 해당하는 것을 추출하게 하였기 때문에 결과도 다음과 같다.
별칭(Aliase)를 이용하여 잠재적인 에러와 모호성을 방지한 서브쿼리문
1 2 3 4 5 6 | SELECT E.Fname, E.Lname FROM EMPLOYEE AS E WHERE E.Ssn IN (SELECT Essn FROM DEPENDENT AS D WHERE E.Fname=D.Dependent_name AND E.Sex=D.Sex); | cs |
EMPLOYEE와 DEPENDENT 테이블을 Inner Join 하는 서브쿼리문을 확인할 수 있다. 별칭을 사용한 이유는 EMPLOYEE 테이블에 Sex 컬럼과 DEPENDENT 테이블의 Sex 컬럼을 구별하기 위한 것이다.
3. 상호연관 서브쿼리문(Correlated Nested Queries)
EXISTS 연산자
- EXISTS 연산자는 Subquery 데이터가 존재하는가를 체크해 존재 여부(TRUE,FALSE)를 결과로 반환한다.
- EXISTS절에는 반드시 메인 쿼리와 연결이 되는 조인 조건을 가지고 있어야 한다.
- subquery에서 결과 행을 찾으면, inner query 수행을 중단하고 TRUE를 반환한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | -- 아래 예처럼 emp 테이블을 통해 사원들이 속한 부서번호의 정보만 조회하는 경우 -- 추출하고자 하는 대상은 dept 테이블이지만 emp 테이블과 조인하여 부서번호를 -- 체크해야 한다. -- 두 테이블의 관계가 1 : M 이므로 불필요하게 EMP 테이블을 모두 액세스하고 -- DISTINCT로 중복 제거를 한다. SELECT DISTINCT d.deptno, d.dname FROM dept d, emp e WHERE d.deptno = e.deptno; -- EXISTS를 사용하는 Subquery로 변경 -- 추출하고자 하는 대상만을 FROM절에 놓고 emp테이블은 체크만 하기위해 -- EXISTS절에 위치시켰으며 이로 인해 수행속도가 대폭 감소하게 된다. SELECT d.deptno, d.dname FROM dept d WHERE EXISTS ( SELECT 1 FROM emp e WHERE e.deptno = d.deptno); |
UNIQUE 연산자
중복된 값을 가진 튜플이 존재하지 않을 때 TRUE를 반환하는 연산자이다.
Attribute의 이름을 변경하는 쿼리문
1 2 3 | SELECT E.Lname AS Employee_name, S.Lname AS Supervisor_name FROM EMPLOYEE AS E, EMPLOYEE AS S WHERE E.Super_ssn = S.Ssn; | cs |
Attribute의 이름을 'AS'를 이용하여 변경하였다. Self Join을 하여 2개의 Lname을 추출하였다.
단일 Join 테이블을 만든 쿼리문
1 2 3 4 | SELECT Fname, Lname, Address FROM (EMPLOYEE JOIN DEPARTMENT ON Dno = Dnumber) WHERE Dname = 'Research'; | cs |
이 쿼리문은 EMPLOYEE, DEPARTMENT 테이블을 Dno=Dnumber로 조인을 하여 단일 Join 테이블로 만든 쿼리문이다. 아래 쿼리문과 동일한 결과를 가진다.
1 2 3 | SELECT Fname, Lname, Address FROM EMPLOYEE, DEPARTMENT WHERE Dno = Dnumber AND Dname = 'Research'; | cs |
집계함수(Aggregate function)의 이해
- - GROUP BY절을 이용하여 그룹 당 하나의 결과로 그룹화 할 수 있다.
- - HAVING절을 사용하여 집계함수를 이용한 조건 비교를 할 수 있다.
- - MIN, MAX 함수는 모든 자료형에 사용 할 수 있다.
- - 일반적으로 가장 많이 사용하는 집계함수에는AVG(평균), COUNT(개수), MAX(최대값), MIN(최소값), SUM(합계) 등이 있다.
COUNT
COUNT 함수는 검색된 행의 수를 반환 한다.
1 2 3 4 5 6 | -- 검색된 행의 총 수 4개를 반환. 즉 4개의 부서가 존재한다. SELECT COUNT (deptno) FROM dept; COUNT (DEPTNO) ------------- 4 |
MAX
MAX 함수는 컬럼값 중에서 최대값을 반환 한다.
1 2 3 4 5 6 | -- sal 컬럼값 중에서 제일 큰값을 반환. 즉 가장 큰 급여를 반환. SELECT MAX (sal) salary FROM emp; SALARY ------- 5000 |
MIN
MIN 함수는 컬럼값 중에서 최소값을 반환 한다.
1 2 3 4 5 6 | -- sal 컬럼값 중에서 가장 작은 값 반환. 즉 가장 적은 급여를 반환 SELECT MIN (sal) salary FROM emp; SALARY ------- 800 |
AVG
AVG 함수는 평균 값을 반환 한다.
1 2 3 4 5 6 7 8 | -- 부서번호 30의 사원 평균 급여를 소수점 1자리 이하에서 반올림 SELECT ROUND( AVG (sal),1) salary FROM emp WHERE deptno = 30; SALARY ------ 1566.7 |
SUM
SUM 함수는 검색된 컬럼의 합을 반환 한다.
1 2 3 4 5 6 7 8 | -- 부서번호 30의 사원 급여 합계를 조회. SELECT SUM (sal) salary FROM emp WHERE deptno = 30; SALARY ------- 9400 |
STDDEV
STDDEV 함수는 표준편차를 반환 한다.
1 2 3 4 5 6 7 8 | -- 부서번호 30의 사원 급여 표준편차를 반환. SELECT ROUND(STDDEV(sal),3) salary FROM emp WHERE deptno = 30; SALARY -------- 668.331 |
집계함수 예
아래는 부서별 사원수, 최대급여, 최소급여, 급여합계, 평균급여를 급여합게 순으로 조회하는 예이다.
1 2 3 4 5 6 7 8 9 10 11 12 13 | SELECT deptno 부서번호, COUNT (*) 사원수, MAX (sal) 최대급여, MIN (sal) 최소급여, SUM (sal) 급여합계, ROUND( AVG (sal)) 평균급여 FROM emp GROUP BY deptno ORDER BY SUM (sal) DESC ; 부서번호 사원수 최대급여 최소급여 급여합계 평균급여 ------- -------- --------- -------- --------- --------- 20 5 3000 800 10875 2175 30 6 2850 950 9400 1567 10 3 5000 1300 8750 2917 |
GROUP BY와 HAVING의 이해
- GROUP BY 함수는 집계 함수와 자주 사용된다. 특정 부서의 직원들의 급여의 총합과 같은 특정 그룹의 데이터를 추출할 때 사용한다. 집계함수와 사용하지 않는다면 DISTINCT와 비슷한 기능을 가진다.
- HAVING은 GROUP BY 절과 함께 사용이 된다. WHERE 절에서는 집계함수를 사용할 수 없다. 이 때 HAVING을 사용한다.
1 2 3 4 5 6 7 | SELECT Dnumber, COUNT(*) FROM DEPARTMENT, EMPLOYEE WHERE Dnumber = Dno AND Salary>40000 AND (SELECT Dno FROM EMPLOYEE GROUP BY Dno HAVING COUNT(*)>3); | cs |
위의 쿼리문은 GROUP BY와 HAVING을 사용한 쿼리이다.
서브쿼리를 보면 EMPLOYEE 테이블에서 직원수가 3명 초과인 Dno(부서번호)를 가져온다. 이 때 WHERE 절에 HAVING을 사용하는 것을 확인할 수 있다.
오늘은 서브쿼리에 대해 공부해보았습니다. 서브쿼리는 제약조건, 사용 방식, 목적을 정확히 알아야 사용할 수 있어요. 다음 시간에는 VIEW에 대한 포스팅을 올릴게요!!
'Computer Science' 카테고리의 다른 글
[도분설] 도메인 모델링 (0) | 2018.10.11 |
---|---|
[데이터베이스] VIEW 테이블(가상 테이블) (0) | 2018.10.10 |
[데이터베이스] SQL 제약조건 (0) | 2018.10.08 |
[백준] 문자열 분석 10820번 (0) | 2018.10.03 |
[백준] 단어의 개수 1152번 (0) | 2018.10.03 |
- Total
- Today
- Yesterday
- 도커
- 부동산공부
- 폭포수
- front
- resize
- 열반스쿨기초반
- Inception
- 2023년
- 항해플러스백엔드
- 월급쟁이부자들
- 유즈케이스
- 관계대수
- github
- push_back
- GIT
- 깃허브
- 개발자 회고
- 인셉션
- 내년은 빡세게!!
- Spring boot
- 월부닷컴
- pop_back
- 재테크공부
- 항해솔직후기
- ```````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````
- Use case
- 깃
- 항해플러스후기
- 파라메터
- docker
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |