반응형

본 글은 책 "칼퇴족 김대리는 알고 나만 모르는 SQL 기초 편"의 정리 내용입니다.

 

데이터 수정


1) 모든 행의 데이터 수정 (주의 필요)

UPDATE 테이블명
SET 열이름 = 변경할 값;

 

2) 특정한 행의 데이터 수정

UPDATE 테이블명
SET 열이름= 변경할 값
WHERE 조건절;

 

특정한 행의 데이터를 수정하는 예

 

예제


테이블: 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. 위 테이블에서 CUST_ID를 1111로 수정하는 쿼리문을 작성해보자

SSN PARTY_NM CUST_ID TEL_NO MOBILE_NO
570 AR KIM 1111 02-555-6678 010-1111-1111
691 SH HONG 1111 031-4456-9887 010-2222-2222
831 MK KANG 1111 051-999-8888 010-3333-3333
710 JH KIM 1111 032-333-1111 010-4444-4444
770 JH LEE 1111 033-111-3355 010-5555-5555
650 JH RYU 1111 02-6666-4444 010-6666-6666
820 YC JUNG 1111 02-2222-1111 010-7777-7777
891 JH JUN 1111 031-224-2222 010-8888-8888
901 SH LEE 1111 033-333-3333 010-9999-9999
더보기
UPDATE CUST_PARTY
SET CUST_ID = 1111;

 

Q2. CUST_PARTY 테이블에서 SSN열 값이 901인 고객의 MOBILE_NO를 010-9988-5555로 수정하는 쿼리문을 작성해보자

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-9988-5555
더보기
UPDATE CUST_PARTY
SET MOBILE_NO = '010-9988-5555'
WHERE SSN=901;

 

반응형

'SQL' 카테고리의 다른 글

[SQL] 테이블 삭제 (DELETE FROM)  (0) 2022.02.23
[SQL] 데이터 삽입 (INSERT INTO)  (0) 2022.02.22
[SQL] 하위 쿼리( Sub-query)  (0) 2022.02.22
[SQL] 테이블 행 합치기 (UNION)  (0) 2022.02.22
[SQL] 테이블 합치기 (FULL OUTER JOIN)  (0) 2022.02.17
반응형

본 글은 책 "칼퇴족 김대리는 알고 나만 모르는 SQL 기초 편"의 정리 내용입니다.

 

테이블 삭제


1) 테이블의 모든 열 삭제 (주의 필요)

DELETE FROM 테이블명;

 

2) 테이블의 일부인 부분 행들을 삭제 

DELETE FROM 테이블명
WHERE 조건절;

부분 행을 삭제하는 쿼리문의 예

 

예제


테이블: 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. 위 테이블에 아래의 값들을 삭제하는 쿼리문을 작성해보자

SSN: 891
PARTY_NM: JH JUN
CUST_ID: 6989
TEL_NO: 031-224-2222
MOBILE_NO: 010-8888-9999

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
901 SH LEE 5570 033-333-3333 010-9999-9999
더보기
DELETE FROM CUST_PARTY
WHERE SSN = 891;

 

 

반응형

'SQL' 카테고리의 다른 글

[SQL] 데이터 수정 (UPDATE, SET)  (0) 2022.02.23
[SQL] 데이터 삽입 (INSERT INTO)  (0) 2022.02.22
[SQL] 하위 쿼리( Sub-query)  (0) 2022.02.22
[SQL] 테이블 행 합치기 (UNION)  (0) 2022.02.22
[SQL] 테이블 합치기 (FULL OUTER JOIN)  (0) 2022.02.17
반응형

본 글은 책 "칼퇴족 김대리는 알고 나만 모르는 SQL 기초 편"의 정리 내용입니다.

 

데이터 삽입


  1. 완전한 행 삽입
INSERT INTO 테이블명
VALUES(값1, 값2, 값3);

데이터 삽입의 예

 

2. 열이름과 함께 완전한 행 삽입

INSERT INTO 테이블명(열이름1, 열이름2, 열이름3)
VALUES(값1, 값2, 값3);

열이름을 이용한 데이터 삽입의 예

 

3. 부분 행 삽입

INSERT INTO 테이블명(열이름1, 열이름3)
VALUES(값1, 값3);

 

4. SQL 쿼리문의 결과를 삽입

INSERT INTO 테이블명(열이름1, 열이름2, 열이름3)
SELECT 열이름1, 열이름2, 열이름 FROM 테이블명2 WHERE 조건절;
  • SQL 문장 결과 전체를 삽입하고 싶을 경우 VALUES 키워드 대신 하위 쿼리 사용

 

예제


테이블: 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. 위 테이블에 아래의 값들을 삽입해보자

SSN : 550
PARTY_NM: MJ YOO
CUST_ID: 8828
TEL_NO: 02-312-1111
MOBILE_NO: 010-1122-1111

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
550 MJ YOO 8828 02-312-1111 010-1122-1111
더보기

 

INSERT INTO CUST_PARTY
VALUES (550, 'MJ YOO', 8828, '02-312-1111', '010-1122-1111');

 

Q2. 위 테이블에 아래의 값들을 삽입해보자

SSN: 551
PARTY_NM: MJ YOO
CUST_ID: 8828
TEL_NO: 02-312-1111
MOBILE_NO 열에는 NULL값

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
550 MJ YOO 8828 02-312-1111 010-1122-1111
551 MJ YOO 8828 02-312-1111 NULL
더보기
INSERT INTO CUST_PARTY(SSN, PARTY_NM, CUST_ID, TEL_NO)
VALUES (551, 'MJ YOO', 8828, '02-312-1111');

 

반응형

'SQL' 카테고리의 다른 글

[SQL] 데이터 수정 (UPDATE, SET)  (0) 2022.02.23
[SQL] 테이블 삭제 (DELETE FROM)  (0) 2022.02.23
[SQL] 하위 쿼리( Sub-query)  (0) 2022.02.22
[SQL] 테이블 행 합치기 (UNION)  (0) 2022.02.22
[SQL] 테이블 합치기 (FULL OUTER JOIN)  (0) 2022.02.17
반응형

본 글은 책 "칼퇴족 김대리는 알고 나만 모르는 SQL 기초 편"의 정리 내용입니다.

 

하위 쿼리 (Sub-query)


  • SQL 문장 안에 포함되는 또 다른 SQL 문장
  • 복잡한 SQL 문장을 간단히 만들고, 데이터 처리 속도를 빠르게 향상 시킬 수 있음

 

하위 쿼리는 크게 FROM 절과 WHERE 조건절에서 활용될 수 있음

FROM 절의 하위 쿼리


사용되는 예

  1. 조건에 맞는 대상자를 선정 후 요약
  2. 테이블 조인

 

예제


  • 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 기초 편"의 정리 내용입니다.

 

UNION 연산자는 두 개 이상의 테이블의 행을 합칠 때 사용

UNION 연산자를 활용한 테이블 행 합치기 예

 

UNION 연산자


SELECT 열이름들 FROM 테이블명1 WHERE 조건절
UNION
SELECT 열이름들 FROM 테이블명2 WHERE 조건절;

 

예제 


  • 총 3가지 테이블을 사용

1. 고객원장 테이블: CUSTOMERS

CUST_ID CUST_NM HOME_TEL
5464 JH KIM 02-333-1111
6570 LY KIM 031-111-1133
8780 AR KIM 032-998-5555
5632 KK LEE 02-6677-8888
2445 HJ WANG 055-4444-5666
3210 HH AN 031-888-0111
2596 DK SUNG 02-113-3331
더보기
CREATE TABLE CUSTOMERS
(
CUST_ID INT NOT NULL,
CUST_NM CHAR(20) NOT NULL,
HOME_TEL CHAR(20) NOT NULL,
PRIMARY KEY('CUST_ID')
);

INSERT INTO CUSTOMERS
VALUES
(5464, 'JH KIM', '02-333-1111'),
(6570, 'LY KIM', '031-111-1133'),
(8780, 'AR KIM', '032-998-5555'),
(5632, 'KK LEE', '02-6677-8888'),
(2445, 'HJ WANG', '055-4444-5666'),
(3210, 'HH AN', '031-888-0111'),
(2596, 'DK SUNG', '02-113-3331');

 

2. 주문 테이블: ORDERS

ORDER_ID CUST_ID EMP_ID ORDER_DT
10000 2596 23480 2013-12-06
10001 5464 16780 2013-11-01
10002 3210 63278 2014-03-02
10003 2445 15501 2014-02-23
10004 5632 15687 2013-11-13
더보기
CREATE TABLE ORDERS (
	ORDER_ID	INTEGER NOT NULL,
	CUST_ID	INTEGER NOT NULL,
	EMP_ID	INTEGER NOT NULL,
	ORDER_DT	TEXT NOT NULL,
	PRIMARY KEY("ORDER_ID")
);

INSERT INTO ORDERS
VALUES
(10000, 2596, 23480, '2013-12-06'),
(10001, 5464, 16780, '2013-11-01'),
(10002, 3210, 63278, '2014-03-02'),
(10003, 2445, 15501, '2014-02-23'),
(10004, 5632, 15687, '2013-11-13');

 

3. 직원 정보 테이블:테이블: EMPLOYEE

EMP_ID GRADE NM TELNO
15501 8 YK MO 5740
15687 8 SS CHANG 5547
16780 5 HY YOO 2327
63278 7 JW PARK 2304
87871 7 SW HONG 2367
23578 6 JI CHOI 4654
32480 6 JM CHA 1270
23480 5 KE LEE 5466
더보기
CREATE TABLE EMPLOYEE
(
EMP_ID INT NOT NULL,
GRADE INT NOT NULL,
NM CHAR(20) NOT NULL,
TELNO INT NOT NULL,
PRIMARY KEY('EMP_ID'));

INSERT INTO EMPLOYEE
VALUES
(15501, 8, 'YK MO', 5740),
(15687, 8, 'SS CHANG', 5547),
(16780, 5, 'HY YOO', 2327),
(63278, 7, 'JW PARK', 2304),
(87871, 7, 'SW HONG', 2367),
(23578, 6, 'JI CHOI', 4654),
(32480, 6, 'JM CHA', 1270),
(23480, 5, 'KE LEE', 5466);

 

Q1. CUSTOMERS와 EMPLOYEE 테이블을 이용하여 직원 이름과 고객 이름을 합쳐서 하나의 열로 오름차순으로 출력 

NM
AR KIM
DK SUNG
HH AN
HJ WANG
HY YOO
JH KIM
JI CHOI
JM CHA
JW PARK
KE LEE
KK LEE
LY KIM
SS CHANG
SW HONG
YK MO
더보기
SELECT CUSTOMERS.CUST_NM AS NM FROM CUSTOMERS
UNION
SELECT EMPLOYEE.NM AS NM FROM EMPLOYEE
ORDER BY 1;

 

Q2. 위 문제에서 ‘NM’이라는 별칭을 주지 않고 아래와 같이 출력한다면 결과는?

SELECT CUSTOMERS.CUST_NM FROM CUSTOMERS
UNION
SELECT EMPLOYEE.NM FROM EMPLOYEE
ORDER BY 1;
더보기
CUST_NM
AR KIM
DK SUNG
HH AN
HJ WANG
HY YOO
JH KIM
JI CHOI
JM CHA
JW PARK
KE LEE
KK LEE
LY KIM
SS CHANG
SW HONG
YK MO

 

주의할 점


1. UNION 연산자를 사용할 때 합쳐지는 SELECT 문의 열의 숫자는 반드시 동일해야 함

테이블 열의 수가 다르면 UNION 연산자 사용 불가능

  • 위와 같이 CUSTOMERS 테이블에서는 2개의 열, EMPLOYEE 테이블에서는 1개의 열을 선택하여 UNION 연산하면  에러 발생
  • Result: SELECTs to the left and right of UNION do not have the same number of result columns

 

UNION ALL 연산자


SELECT 열이름들 FROM 테이블명1 WHERE 조건절
UNION ALL
SELECT 열이름들 FROM 테이블명2 WHERE 조건절;
  • UNION과 달리, UNION ALL은 중복된 행도 모두 출력

 

예시 - CUSTOMERS와 ORDERS 테이블 이용하여 고객아이디를 합쳐서 출력

1) UNION 사용
- 중복되는 행을 출력하지 않음

SELECT CUSTOMERS.CUST_ID FROM CUSTOMERS
UNION
SELECT ORDERS.CUST_ID FROM ORDERS;
CUST_ID
2445
2596
3210
5464
5632
6570
8780

 

2) UNION ALL 사용
- 중복되는 행 모두 출력

SELECT CUSTOMERS.CUST_ID FROM CUSTOMERS
UNION ALL
SELECT ORDERS.CUST_ID FROM ORDERS;
CUST_ID
2445
2596
3210
5464
5632
6570
8780
2596
5464
3210
2445
5632
반응형
반응형

본 글은 책 "칼퇴족 김대리는 알고 나만 모르는 SQL 기초 편"의 정리 내용입니다.

 

OUTER JOIN에는 크게 LEFT, RIGHT, FULL 3가지 방법이 있다. 본 글에서는 FULL OUTER JOIN을 다룬다.

FULL OUTER JOIN


  • LEFT OUTERT JOIN과 RIGHT OUTER JOIN을 합친 결과
  • OUTER는 생략 가능

FULL JOIN을 이용한 테이블 합치기

더보기
CREATE TABLE ADDR1 (
	"CUST_ID"	INT NOT NULL,
	"HOME_ADDR1"	CHAR(50) NOT NULL,
	"HOME_ADDR2"	CHAR(50) NOT NULL,
	PRIMARY KEY('CUST_ID')
);

INSERT INTO ADDR1
VALUES
(5465, '서울시 강남구 역삼동', '111-11'),
(2354, '서울시 종로구 공평동', '222-22'),
(5410, '서울시 중구 서소문동', '333-33'),
(6511, '서울시 송파구 문정동', '444-44');


CREATE TABLE MOBILE1 (
	"CUST_ID"	INT NOT NULL,
	"MOBILE_NO"	CHAR(50) NOT NULL,
	PRIMARY KEY('MOBILE_NO')
);

INSERT INTO MOBILE1
VALUES
(5465, '010-1111-1111'),
(2354, '010-2222-2222'),
(5410, '010-3333-3333'),
(5410, '010-7777-7777'),
(7979, '010-7979-7979');

 

위의 합쳐진 테이블을 만들기 위한 SQL 문장은?


SELECT ADDR1.CUST_ID, ADDR1.HOME_ADDR1, ADDR1.HOME_ADDR2,
       MOBILE1.CUST_ID AS CUST_ID2, MOBILE1.MOBILE_NO

FROM ADDR1 FULL JOIN MOBILE1
ON ADDR1.CUST_ID = MOBILE1.CUST_ID;
  • 다만 sqlite에서는 FULL JOIN을 지원하지 않음
    • Error: RIGHT and FULL OUTER JOINs are not currently supported
반응형
반응형

본 글은 책 "칼퇴족 김대리는 알고 나만 모르는 SQL 기초 편"의 정리 내용입니다.

 

OUTER JOIN에는 크게 LEFT, RIGHT, FULL 3가지 방법이 있다. 본 글에서는 RIGHT OUTER JOIN을 다룬다.

RIGHT OUTER JOIN (외부 조인)


  • RIGHT OUTER JOIN이란 오른쪽 테이블을 기준으로 왼쪽 테이블을 붙이는 것을 의미
  • 'RIGHT JOIN'이라는 명령어로도 사용 가능 (OUTER 명령어 생략 가능)

RIGHT JOIN을 이용한 테이블 합치기

더보기
CREATE TABLE ADDR1 (
	"CUST_ID"	INT NOT NULL,
	"HOME_ADDR1"	CHAR(50) NOT NULL,
	"HOME_ADDR2"	CHAR(50) NOT NULL,
	PRIMARY KEY('CUST_ID')
);

INSERT INTO ADDR1
VALUES
(5465, '서울시 강남구 역삼동', '111-11'),
(2354, '서울시 종로구 공평동', '222-22'),
(5410, '서울시 중구 서소문동', '333-33'),
(6511, '서울시 송파구 문정동', '444-44');


CREATE TABLE MOBILE1 (
	"CUST_ID"	INT NOT NULL,
	"MOBILE_NO"	CHAR(50) NOT NULL,
	PRIMARY KEY('MOBILE_NO')
);

INSERT INTO MOBILE1
VALUES
(5465, '010-1111-1111'),
(2354, '010-2222-2222'),
(5410, '010-3333-3333'),
(5410, '010-7777-7777'),
(7979, '010-7979-7979');

 

특징


  1. 오른쪽 MOBILE1 테이블의 모든 값을 나타내고, 오른쪽 테이블을 기준으로 왼쪽 ADDR1 테이블이 붙음

  2. 한 개의 키 값에 두 개 이상의 값을 가지고 있으면 모든 값이 붙음
    (MOBILE1 테이블에 CUST_ID가 5410인 고객의 휴대폰 번호는 2개가 있다는 것을 알 수 있음)

  3. 오른쪽 테이블의 키 값을 기준으로 왼쪽 테이블의 키 값이 존재하지 않는다면 NULL값으로 처리
    (CUST_ID가 7979인 고객의 HOME_ADDR1, HOME_ADDR2는 NULL값으로 처리됨)

 

위의 합쳐진 테이블을 만들기 위한 SQL 문장은?


SELECT ADDR1.CUST_ID, ADDR1.HOME_ADDR1, ADDR1.HOME_ADDR2,
       MOBILE1.CUST_ID AS CUST_ID2, MOBILE1.MOBILE_NO

FROM ADDR1 RIGHT JOIN MOBILE1
ON ADDR1.CUST_ID = MOBILE1.CUST_ID;
  • 다만 sqlite에서는 RIGHT JOIN을 지원하지 않음
    • Error: RIGHT and FULL OUTER JOINs are not currently supported
  • FROM 절에서 테이블의 위치를 변경하여 LEFT JOIN을 이용해 위의 결과를 얻을 수 있음
SELECT ADDR1.CUST_ID, ADDR1.HOME_ADDR1, ADDR1.HOME_ADDR2,
       MOBILE1.CUST_ID AS CUST_ID2, MOBILE1.MOBILE_NO

FROM MOBILE1 LEFT JOIN ADDR1
ON ADDR1.CUST_ID = MOBILE1.CUST_ID;
반응형
반응형

본 글은 책 "칼퇴족 김대리는 알고 나만 모르는 SQL 기초 편"의 정리 내용입니다.

 

OUTER JOIN에는 크게 LEFT, RIGHT, FULL 3가지 방법이 있다. 본 글에서는 LEFT OUTER JOIN을 다룬다.

LEFT OUTER JOIN (외부 조인)


  • LEFT OUTER JOIN이란 쪽 테이블을 기준으로 오른쪽 테이블을 붙이는 것을 의미
  • 'LEFT JOIN'이라는 명령어로 OUTER 명령어 생략 가능

LEFT JOIN을 이용한 테이블 합치기

더보기
CREATE TABLE ADDR1 (
	"CUST_ID"	INT NOT NULL,
	"HOME_ADDR1"	CHAR(50) NOT NULL,
	"HOME_ADDR2"	CHAR(50) NOT NULL,
	PRIMARY KEY('CUST_ID')
);

INSERT INTO ADDR1
VALUES
(5465, '서울시 강남구 역삼동', '111-11'),
(2354, '서울시 종로구 공평동', '222-22'),
(5410, '서울시 중구 서소문동', '333-33'),
(6511, '서울시 송파구 문정동', '444-44');


CREATE TABLE MOBILE1 (
	"CUST_ID"	INT NOT NULL,
	"MOBILE_NO"	CHAR(50) NOT NULL,
	PRIMARY KEY('MOBILE_NO')
);

INSERT INTO MOBILE1
VALUES
(5465, '010-1111-1111'),
(2354, '010-2222-2222'),
(5410, '010-3333-3333'),
(5410, '010-7777-7777'),
(7979, '010-7979-7979');

특징


  1. 왼쪽 ADDR1 테이블의 모든 값을 나타내고, 왼쪽 테이블을 기준으로 오른쪽 MOBILE1 테이블이 붙은 형태

  2. 한 개의 키 값에 두 개 이상의 값을 가지고 있으면 모든 값이 붙음
     (MOBILE1 테이블 ‘CUST_ID’ 열의 5410)

  3. 왼쪽 테이블의 키 값을 기준으로 오른쪽 테이블의 키 값이 존재하지 않는다면 NULL값 처리
    (CUST_ID가 6511인 고객의 MOBILE_NO는 NULL값 처리)

 

위의 합쳐진 테이블을 만들기 위한 SQL 문장은?


SELECT ADDR1.CUST_ID, ADDR1.HOME_ADDR1, ADDR1.HOME_ADDR2,
       MOBILE1.CUST_ID AS CUST_ID2, MOBILE1.MOBILE_NO

FROM ADDR1 LEFT JOIN MOBILE1
ON ADDR1.CUST_ID = MOBILE1.CUST_ID;
반응형
반응형

본 글은 책 "칼퇴족 김대리는 알고 나만 모르는 SQL 기초 편"의 정리 내용입니다.

INNER JOIN (내부 조인)


더보기
CREATE TABLE ADDR
(
CUST_ID INT NOT NULL,
HOME_ADDR1 CHAR(50) NOT NULL,
HOME_ADDR2 CHAR(50) NOT NULL,
PRIMARY KEY('CUST_ID')
);

INSERT INTO ADDR
VALUES
(5465, '서울시 강남구 역삼동', '111-11'),
(2354, '서울시 종로구 공평', '222-22'),
(5410, '서울시 중구 서소문동', '333-33');

CREATE TABLE MOBILE
(
CUST_ID INT NOT NULL,
MOBILE_NO CHAR(50) NOT NULL,
PRIMARY KEY('CUST_ID')
);

INSERT INTO MOBILE
VALUES
(5465, '010-1111-1111'),
(2354, '010-2222-2222');

 

  • 2개의 테이블을 하나의 테이블로 합치는 방법들 중 하나
    • ADDR 테이블에서 CUST_ID, MOBILE 테이블에서 CUST_ID가 공통으로 존재하는 Key

 

SELECT ADDR.*, MOBILE.MOBILE_NO
FROM ADDR INNER JOIN MOBILE 
ON ADDR.CUST_ID = MOBILE.CUST_ID;
  • 공통된 키 열을 매칭 시킬 때 ON 키워드를 사용
  • 위 코드의 두 번째 줄에서 아래와 같이 ‘ADDR’과 ‘MOBILE’의 위치를 변경해서 작성해도 똑같이 동작함
SELECT ADDR.*, MOBILE.MOBILE_NO
FROM MOBILE INNER JOIN ADDR
ON ADDR.CUST_ID = MOBILE.CUST_ID;

 

예제 


  • 총 3가지 테이블을 사용

1. 고객원장 테이블: CUSTOMERS

CUST_ID CUST_NM HOME_TEL
5464 JH KIM 02-333-1111
6570 LY KIM 031-111-1133
8780 AR KIM 032-998-5555
5632 KK LEE 02-6677-8888
2445 HJ WANG 055-4444-5666
3210 HH AN 031-888-0111
2596 DK SUNG 02-113-3331
더보기
CREATE TABLE CUSTOMERS
(
CUST_ID INT NOT NULL,
CUST_NM CHAR(20) NOT NULL,
HOME_TEL CHAR(20) NOT NULL,
PRIMARY KEY('CUST_ID')
);

INSERT INTO CUSTOMERS
VALUES
(5464, 'JH KIM', '02-333-1111'),
(6570, 'LY KIM', '031-111-1133'),
(8780, 'AR KIM', '032-998-5555'),
(5632, 'KK LEE', '02-6677-8888'),
(2445, 'HJ WANG', '055-4444-5666'),
(3210, 'HH AN', '031-888-0111'),
(2596, 'DK SUNG', '02-113-3331');

 

2. 주문 테이블: ORDERS

ORDER_ID CUST_ID EMP_ID ORDER_DT
10000 2596 23480 2013-12-06
10001 5464 16780 2013-11-01
10002 3210 63278 2014-03-02
10003 2445 15501 2014-02-23
10004 5632 15687 2013-11-13
더보기
CREATE TABLE ORDERS (
	ORDER_ID	INTEGER NOT NULL,
	CUST_ID	INTEGER NOT NULL,
	EMP_ID	INTEGER NOT NULL,
	ORDER_DT	TEXT NOT NULL,
	PRIMARY KEY("ORDER_ID")
);

INSERT INTO ORDERS
VALUES
(10000, 2596, 23480, '2013-12-06'),
(10001, 5464, 16780, '2013-11-01'),
(10002, 3210, 63278, '2014-03-02'),
(10003, 2445, 15501, '2014-02-23'),
(10004, 5632, 15687, '2013-11-13');

 

3. 직원정보 테이블: EMPLOYEE

EMP_ID GRADE NM TELNO
15501 8 YK MO 5740
15687 8 SS CHANG 5547
16780 5 HY YOO 2327
63278 7 JW PARK 2304
87871 7 SW HONG 2367
23578 6 JI CHOI 4654
32480 6 JM CHA 1270
23480 5 KE LEE 5466
더보기
CREATE TABLE EMPLOYEE
(
EMP_ID INT NOT NULL,
GRADE INT NOT NULL,
NM CHAR(20) NOT NULL,
TELNO INT NOT NULL,
PRIMARY KEY('EMP_ID'));

INSERT INTO EMPLOYEE
VALUES
(15501, 8, 'YK MO', 5740),
(15687, 8, 'SS CHANG', 5547),
(16780, 5, 'HY YOO', 2327),
(63278, 7, 'JW PARK', 2304),
(87871, 7, 'SW HONG', 2367),
(23578, 6, 'JI CHOI', 4654),
(32480, 6, 'JM CHA', 1270),
(23480, 5, 'KE LEE', 5466);

 

Q1. CUSTOMERS와 ORDERS 테이블을 이용해 주문 이력이 있는 고객 아이디(CUST_ID), 고객 이름(CUST_NM), 주문번호(ORDER_ID) 출력

CUST_ID CUST_NM ORDER_ID
2596 DK SUNG 10000
5464 JH KIM 10001
3210 HH AN 10002
2445 HJ WANG 10003
5632 KK LEE 10004
더보기
SELECT CUSTOMERS.CUST_ID, CUST_NM, ORDER_ID 
FROM CUSTOMERS INNER JOIN ORDERS
ON CUSTOMERS.CUST_ID = ORDERS.CUST_ID;

 

Q2. 위 3개의 테이블을 이용해 주문이력이 있는 고객아이디(CUST_ID), 고객이름(CUST_NM), 주문번호(ORDER_ID), 판매직원 아이디(EMP_ID) 및 직원 이름(NM) 출력 (3개의 테이블을 합치는 문제)

CUST_ID CUST_NM ORDER_ID EMP_ID NM
2596 DK SUNG 10000 23480 KE LEE
5464 JH KIM 10001 16780 HY YOO
3210 HH AN 10002 63278 JW PARK
2445 HJ WANG 10003 15501 YK MO
5632 KK LEE 10004 15687 SS CHANG
더보기
SELECT TMP1.CUST_ID, TMP1.CUST_NM, TMP2.ORDER_ID, TMP3.EMP_ID, TMP3.NM
FROM CUSTOMERS TMP1
	 INNER JOIN ORDERS TMP2 ON TMP1.CUST_ID = TMP2.CUST_ID
	 INNER JOIN EMPLOYEE TMP3 ON TMP2.EMP_ID = TMP3.EMP_ID;

- 각 테이블에 TMP1, TMP2, TMP3 라는 별칭을 붙여서 쿼리문 작성

 

참고


  • 조인 조건을 지정하지 않은 채 두 테이블을 조인하면 곱집합이 됨
    • 위의 Q1 에서 ON 절을 제외하면 조인 조건이 지정되지 않아 두 테이블 각각의 행수를 곱한 7*5 = 35 개의 행이 출력됨
    • SELECT CUSTOMERS.CUST_ID, CUSTOMERS.CUST_NM, ORDERS.ORDER_ID
      FROM CUSTOMERS INNER JOIN ORDERS;
      
CUST_ID CUST_NM ORDER_ID
5464 JH KIM 10000
5464 JH KIM 10001
5464 JH KIM 10002
5464 JH KIM 10003
5464 JH KIM 10004
6570 LY KIM 10000
6570 LY KIM 10001
6570 LY KIM 10002
6570 LY KIM 10003
6570 LY KIM 10004
8780 AR KIM 10000
8780 AR KIM 10001
8780 AR KIM 10002
8780 AR KIM 10003
8780 AR KIM 10004
5632 KK LEE 10000
5632 KK LEE 10001
5632 KK LEE 10002
5632 KK LEE 10003
5632 KK LEE 10004
2445 HJ WANG 10000
2445 HJ WANG 10001
2445 HJ WANG 10002
2445 HJ WANG 10003
2445 HJ WANG 10004
3210 HH AN 10000
3210 HH AN 10001
3210 HH AN 10002
3210 HH AN 10003
3210 HH AN 10004
2596 DK SUNG 10000
2596 DK SUNG 10001
2596 DK SUNG 10002
2596 DK SUNG 10003
2596 DK SUNG 10004
반응형
반응형

본 글은 책 "칼퇴족 김대리는 알고 나만 모르는 SQL 기초 편"의 정리 내용입니다.

그룹화된 데이터 필터링하기


SELECT 그룹화할 열 이름1, 
FROM 테이블명
WHERE 조건절
GROUP BY 열 이름1
HAVING 집계함수조건;

 

WHERE 조건절과의 차이점

  • WHERE 조건절은 무수히 많은 데이터에서 원하는 행만 보고 싶을 때 사용
  • HAVING 조건절은 행이 아닌 그룹화된 변수(GROUP BY 절 결과 이후)에 대해 필터링할 경우에 사용

 

2022.02.16 - [SQL] - [SQL] 데이터의 그룹화 (GROUP BY)

위의 글의 테이블을 참고하여 GROUP BY절을 이용하여 추출한 결과는 아래와 같다.

이름 ENG MATH GENDER
김필호 28 49 남자
이치훈 68 98 남자
김영숙 87 87 여자
성은영 65 78 여자

 

SELECT GENDER,
       AVG(ENG) AS ENG_AVERAGE,
       AVG(MATH) AS MATH_AVERAGE
FROM CLASS_SCORE
GROUP BY GENDER;
GENDER ENG_AVERAGE MATH_AVERAGE
남자 48.0 73.5
여자 76.0 82.5
  • GROUP BY 를 사용하여 성별(Gender)로 평균값을 계산 및 출력

 

이때, 수학 평균 정수(MATH_AVERAGE)가 80 이상인 그룹만 출력하길 원한다면? -> HAVING 절을 사용할 수 있다. 

SELECT GENDER,
       AVG(ENG) AS ENG_AVERAGE,
       AVG(MATH) AS MATH_AVERAGE
FROM CLASS_SCORE
GROUP BY GENDER
HAVING MATH_AVERAGE >=80;
GENDER ENG_AVERAGE MATH_AVERAGE
여자 76.0 82.5

 

예제 


고객구매 테이블: PROD_SALES

  • 열 설명: 고객 이름, 제품 코드, 구매금액
CUST_NM PRD_ID SALES_AMT
LEE 546 3000
KIM 324 4780
KANG 564 87900
KWON 556 45478
KIM 254 3000
YOO 567 78900
PARK 877 89787
LEE 890 10000
KIM 787 2341
PARK 566 50000
더보기
CREATE TABLE PROD_SALES
(
	CUST_NM CHAR(20) NOT NULL,
	PRD_ID INT NOT NULL,
	SALES_AMT INT NOT NULL,
	PRIMARY KEY('PRD_ID')
);

INSERT INTO PROD_SALES
VALUES
('LEE', 546,  3000),
('KIM', 324,  4780),
('KANG', 564, 87900),
('KWON', 556, 45478),
('KIM', 254,  3000),
('YOO', 567,  78900),
('PARK', 877, 89787),
('LEE', 890,  10000),
('KIM', 787,  2341),
('PARK', 566, 50000);

 

Q1. 구매 횟수가 두 번 이상인 고객에게 마케팅을 하려고 한다. 마케팅 대상자는 누구일까? 

더보기

A1. 

1단계. 먼저 COUNT 함수와 GROUP BY 절을 이용해 고객별 구매 횟수를 추출

SELECT CUST_NM, COUNT(*)
FROM PROD_SALES
GROUP BY CUST_NM;
CUST_NM COUNT(*)
KANG 1
KIM 3
KWON 1
LEE 2
PARK 2
YOO 1

 

2단계. HAVING 절을 이용해 구매 횟수가 2번 이상인 대상자를 추출

SELECT CUST_NM, COUNT(*)
FROM PROD_SALES
GROUP BY CUST_NM
HAVING COUNT(*)>=2;
CUST_NM COUNT(*)
KIM 3
LEE 2
PARK 2

 

 

Q2. 구매금액의 합이 7만원 이상인 고객에게 마케팅을 하려고 한다. 마케팅 대상자는 누구일까? 

더보기

A1. 

1단계. 먼저 SUM 함수와 GROUP BY 절을 이용해 고객별 구매금액을 추출

SELECT CUST_NM, SUM(SALES_AMT)
FROM PROD_SALES
GROUP BY CUST_NM;
CUST_NM SUM(SALES_AMT)
KANG 87900
KIM 10121
KWON 45478
LEE 13000
PARK 139787
YOO 78900

 

2단계. HAVING 절을 이용해 구매금액의 합이 7만원 이상인 대상자를 추출

SELECT CUST_NM, SUM(SALES_AMT)
FROM PROD_SALES
GROUP BY CUST_NM
HAVING SUM(SALES_AMT)>=70000;
CUST_NM SUM(SALES_AMT)
KANG 87900
PARK 139787
YOO 78900

 

Q3. 구매금액의 평균이 7만원 이상인 고객에게 마케팅을 하려고 한다. 마케팅 대상자는 누구일까?

더보기

A1. 

1단계. 먼저 AVG 함수와 GROUP BY 절을 이용해 고객별 구매금액을 추출

SELECT CUST_NM, AVG(SALES_AMT)
FROM PROD_SALES
GROUP BY CUST_NM;
CUST_NM AVG(SALES_AMT)
KANG 87900
KIM 3373.6667
KWON 45478
LEE 6500
PARK 69893.5
YOO 78900

 

2단계. HAVING 절을 이용해 구매금액의 평균이 7만원 이상인 대상자를 추출

SELECT CUST_NM, AVG(SALES_AMT)
FROM PROD_SALES
GROUP BY CUST_NM
HAVING AVG(SALES_AMT)>=70000;
CUST_NM AVG(SALES_AMT)
KANG 87900
YOO 78900

 

참고


  1. 그룹화 필터링 후 데이터를 정렬할 때 ORDER BY절을 사용할 수 있음
    • 순서는 ORDER BY절이 문장의 항상 마지막에 사용됨
    SELECT 열이름 
    FROM 테이블이름
    WHERE 조건절(개별 행에 대한 필터링) 
    GROUP BY 열이름
    HAVING 조건절(그룹화된 변수에 대한 필터링)
    ORDER BY 열이름
  2. WHERE 조건절의 조건은 데이터가 그룹화되기 전에 필터링하고, HAVING절의 조건은 데이터가 그룹화된 후에 필터링
  • WHERE 절에 의해 제외된 행은 그룹화할 때도 제외되기 때문에 HAVING절의 고려 대상이 아님
반응형

+ Recent posts