반응형
본 글은 책 "칼퇴족 김대리는 알고 나만 모르는 SQL 기초 편"의 정리 내용입니다.
하위 쿼리 (Sub-query)
- SQL 문장 안에 포함되는 또 다른 SQL 문장
- 복잡한 SQL 문장을 간단히 만들고, 데이터 처리 속도를 빠르게 향상 시킬 수 있음
하위 쿼리는 크게 FROM 절과 WHERE 조건절에서 활용될 수 있음
FROM 절의 하위 쿼리
사용되는 예
- 조건에 맞는 대상자를 선정 후 요약
- 테이블 조인
예제
- 2개의 테이블 사용
1. 테이블: CARD_ACCT
SSN | CC_GRADE | ISSUE_DT | CLOSE_DT | VALID_YYMM | CASH_USE_FLG | CC_VARIETY_CD |
570 | 8 | 2012-03-26 | NULL | 201503 | Y | 11111 |
770 | 2 | 2011-12-22 | 2013-12-01 | 201512 | NULL | 44444 |
650 | 8 | 2013-06-08 | NULL | 201806 | Y | 11111 |
820 | 8 | 2013-09-28 | NULL | 201809 | Y | 22222 |
570 | 1 | 2009-11-17 | NULL | 201411 | NULL | 33333 |
770 | 8 | 2010-07-27 | NULL | 201407 | NULL | 22222 |
820 | 2 | 2010-09-11 | NULL | 201509 | Y | 44444 |
820 | 1 | 2013-11-26 | NULL | 201811 | NULL | 33333 |
더보기
CREATE TABLE CARD_ACCT
(
SSN INT NOT NULL,
CC_GRADE INT NOT NULL,
ISSUE_DT CHAR(20) NOT NULL,
CLOSE_DT CHAR(20),
VALID_YYMM INT NOT NULL,
CASH_USE_FLG CHAR(5),
CC_VARIETY_CD INT NOT NULL,
PRIMARY KEY('SSN', 'CC_GRADE')
);
INSERT INTO CARD_ACCT
VALUES
(570, 8, '2012-03-26', NULL, 201503, 'Y', 11111),
(770, 2, '2011-12-22', '2013-12-01', 201512, NULL, 44444),
(650, 8, '2013-06-08', NULL, 201806, 'Y', 11111),
(820, 8, '2013-09-28', NULL, 201809, 'Y', 22222),
(570, 1, '2009-11-17', NULL, 201411, NULL, 33333),
(770, 8, '2010-07-27', NULL, 201407, NULL, 22222),
(820, 2, '2010-09-11', NULL, 201509, 'Y', 44444),
(820, 1, '2013-11-26', NULL, 201811, NULL, 33333);
2. 테이블: CUST_PARTY
SSN | PARTY_NM | CUST_ID | TEL_NO | MOBILE_NO |
570 | AR KIM | 5670 | 02-555-6678 | 010-1111-1111 |
691 | SH HONG | 2357 | 031-4456-9887 | 010-2222-2222 |
831 | MK KANG | 3977 | 051-999-8888 | 010-3333-3333 |
710 | JH KIM | 8988 | 032-333-1111 | 010-4444-4444 |
770 | JH LEE | 7702 | 033-111-3355 | 010-5555-5555 |
650 | JH RYU | 3574 | 02-6666-4444 | 010-6666-6666 |
820 | YC JUNG | 5670 | 02-2222-1111 | 010-7777-7777 |
891 | JH JUN | 6989 | 031-224-2222 | 010-8888-8888 |
901 | SH LEE | 5570 | 033-333-3333 | 010-9999-9999 |
더보기
CREATE TABLE CUST_PARTY
(
SSN INT NOT NULL,
PARTY_NM CHAR(20) NOT NULL,
CUST_ID INT NOT NULL,
TEL_NO CHAR(20) NOT NULL,
MOBILE_NO CHAR(20) NOT NULL,
PRIMARY KEY('SSN')
);
INSERT INTO CUST_PARTY
VALUES
(570, 'AR KIM', 5670, '02-555-6678', '010-1111-1111'),
(691, 'SH HONG', 2357, '031-4456-9887', '010-2222-2222'),
(831, 'MK KANG', 3977, '051-999-8888', '010-3333-3333'),
(710, 'JH KIM', 8988, '032-333-1111', '010-4444-4444'),
(770, 'JH LEE', 7702, '033-111-3355', '010-5555-5555'),
(650, 'JH RYU', 3574, '02-6666-4444', '010-6666-6666'),
(820, 'YC JUNG', 5670, '02-2222-1111', '010-7777-7777'),
(891, 'JH JUN', 6989, '031-224-2222', '010-8888-8888'),
(901, 'SH LEE', 5570, '033-333-3333', '010-9999-9999');
Q1. CARD_ACCT 테이블과 CUST_PARTY 테이블을 이용하여 현재 살아있는 신용카드(CG_GRADE가 1 혹은 2) 보유 고객과 미보유 고객의 수를 나타내면?
A1. 어렵다
SELECT CASE WHEN TMP2.SSN IS NOT NULL THEN 'O'
ELSE 'X' END AS CC_HOLDER,
COUNT(CASE WHEN TMP2.SSN IS NOT NULL THEN 1 ELSE 0 END) AS CNT
FROM CUST_PARTY TMP1
LEFT OUTER JOIN
(SELECT DISTINCT SSN
FROM CARD_ACCT
WHERE CLOSE_DT IS NULL AND CC_GRADE IN (1, 2)) AS TMP2
ON TMP1.SSN = TMP2.SSN
GROUP BY 1;
- 교재에서는 SUM(CASE WHEN TMP2.SSN IS NOT NULL THEN 1 ELSE 0 END) AS CNT 으로 표시되어 있지만 COUNT(CASE WHEN TMP2.SSN IS NOT NULL THEN 1 ELSE 0 END) AS CNT 로 변경해야 함
WHERE 절의 하위 쿼리
SELECT 열이름들
FROM 테이블명
WHERE 열이름 IN (SELECT 열이름 FROM 테이블명2 WHERE 조건절);
- WHERE 조건절에서 하위 쿼리는 IN 연산자와 함께 쓰인다고 생각하면 됨
예시
Q1. CARD_ACCT테이블과 CUST_PARTY 테이블을 이용하여 현재 살아있는 신용카드 보유 고객의 주민등록번호, 이름, 아이디, 자택번호 및 휴대폰 번호를 출력
A1. 하위 쿼리를 사용하지 않는다면 아래와 같이 두 단계로 나누어 SQL 문장을 작성해야 함
1단계
SELECT DISTINCT SSN
FROM CARD_ACCT
WHERE CC_GRADE IN (1, 2) AND CLOSE_DT IS NULL;
SSN |
570 |
820 |
2단계
SELECT *
FROM CUST_PARTY
WHERE SSN IN ('570', '820');
SSN | PARTY_NM | CUST_ID | TEL_NO | MOBILE_NO |
570 | AR KIM | 5670 | 02-555-6678 | 010-1111-1111 |
820 | YC JUNG | 5670 | 02-2222-1111 | 010-7777-7777 |
두 단계를 합쳐서 하위 쿼리를 사용하면 아래와 같음
SELECT *
FROM CUST_PARTY
WHERE SSN IN (SELECT DISTINCT SSN
FROM CARD_ACCT
WHERE CC_GRADE IN (1, 2) AND CLOSE_DT IS NULL);
2단계에서 하드코딩된 WHERE 조건절에 1단계의 쿼리문을 넣어줌
반응형
'SQL' 카테고리의 다른 글
[SQL] 테이블 삭제 (DELETE FROM) (0) | 2022.02.23 |
---|---|
[SQL] 데이터 삽입 (INSERT INTO) (0) | 2022.02.22 |
[SQL] 테이블 행 합치기 (UNION) (0) | 2022.02.22 |
[SQL] 테이블 합치기 (FULL OUTER JOIN) (0) | 2022.02.17 |
[SQL] 테이블 합치기 (RIGHT OUTER JOIN) (0) | 2022.02.17 |