You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
SELECT는 데이터 조작 언어(DML)중 하나이자 데이터 분석에 있어서 가장 많이 사용되는 명령어.
SELECT와 함께 사용되는 절은 FROM / WHERE / GROUP BY / HAVING / ORDER BY 등이 존재.
1-1-1 SELECT + FROM
USE EDU
-- FROM : [MEMBER] 테이블 선택SELECT*FROM [MEMBER]
FROM절은 테이블을 선택하는 명령어.
1-1-2 SELECT + FROM + WHERE
-- WHERE : gender 컬럼값이 'man'으로만 필터링SELECT*FROM [MEMBER]
WHERE gender ='man'
WHERE는 테이블을 특정 조건으로 필터하는 명령어.
1-1-3 SELECT + FROM + WHERE + GROUP BY
-- GROUP BY : addr 컬럼별로 회원(mem_no)수 집계SELECT addr, COUNT(mem_no) AS [회원수집계]
FROM [MEMBER]
WHERE gender ='man'GROUP BY addr
-- GROUP BY : addr, gender 컬럼별로 회원(mem_no)수 집계SELECT addr, gender, COUNT(mem_no) AS [회원수집계]
FROM [MEMBER]
WHERE gender ='man'GROUP BY addr, gender
GROUP BY는 특정 열들을 그룹으로 묶는 명령어.
COUNT는 특정 조건을 만족하는 열의 개수를 구하는 집계 함수. -> 후에 설명.
1-1-4 SELECT + FROM + WHERE + GROUP BY + HAVING
-- HAVING : addr 컬럼별로 회원(mem_no)수가 50이상만 필터링SELECT addr, COUNT(mem_no) AS [회원수집계]
FROM [MEMBER]
WHERE gender ='man'GROUP BY addr
HAVINGCOUNT(mem_no) >=50
HAVING은 GROUP BY된 테이블을 특정 조건으로 필터하는 명령어.
WHERE과 차이점으로는 WHERE은 [FROM + 테이블]로 만들어진 테이블의 행을 필터, HAVING은 [GROUP BY+열]로 만들어진 새로운 테이블의 행을 필터.
1-1-5 SELECT + FROM + WHERE + GROUP BY + HAVING + ORDER BY
-- ORDER BY : addr 컬럼별로 회원(mem_no)수가 높은 순(DESC)으로 정렬SELECT addr, COUNT(mem_no) AS [회원수집계]
FROM [MEMBER]
WHERE gender ='man'GROUP BY addr
HAVINGCOUNT(mem_no) >=50ORDER BYCOUNT(mem_no) DESC
ORDER BY는 조회된 행을 정렬하는 명령어.
DESC는 내림차순 정렬 옵션이며, ASC는 오름차순.
1-2 SQL 문법 vs 실행 순서
SQL 문법 순서 : SELECT -> FROM -> WHERE -> GROUP BY -> HAVING -> ORDER BY
SQL 실행 순서 : FROM -> WHERE -> GROUP BY -> HAVING -> SELECT -> ORDER BY로 SELECT만 실행 순서가 바뀜.
2. 결합(JOIN)
2-1 ERM이란?
ERM(Entity-Relationship Modeling)은 데이터를 구조화하여 데이터베이스에 저장하기 위한 개체-관계 모델링 기법.
위 그림은 개체(Entity)간의 관계(Relationship)를 모델링(Modeling)한 예시이며 한명의 회원이 여러 상품을 주문하는 관계 -> 1:N 관계.
회원은 N개의 상품을 주문할 수 있기 때문에, 회원 및 주문 테이블 관계는 1:N.
상품은 N번 주문될 수 있기 때문에, 주문 및 상품 테이블 관계는 N:1.
1:N 및 N:1 관계는 테이블 간의 관계를 설계할 때 사용되는 용어. 1은 중복 데이터가 아닌 고유한 PRIMARY KEY(PK)이며, N은 PK와 연결되는 중복 데이터가 가능한 FOREIGH KEY(FK).
위의 그림에서 회원 테이블의 PK는 회원번호, 주문 테이블에서의 회원번호는 FK.
위의 그림에서 상품 테이블의 PK는 상품번호, 주문 테이블에서의 상품번호는 FK.
2-2 JOIN
JOIN은 여러 테이블 간의 공통 값을 활용하여 테이블을 결합하는 명령어.
JOIN의 종류는 INNER / OUTER / CROSS / SELF JOIN 총 4가지 종류가 존재.
2-2-1 INNER JOIN
INNER JOIN은 두 테이블 간의 공통 값이 매칭되는 데이터만 조회하는 명령어.
USE EDU
-- INNER JOIN : 공통된 요소들을 통해 결합하는 조인 방식-- [MEMBER] 및 [ORDER] 테이블 공통 값(mem_no) 결합SELECT*FROM [MEMBER] AS A -- [MEMBER] 테이블 별칭 AINNER JOIN [ORDER] AS B -- [ORDER] 테이블 별칭 BONA.mem_no=B.mem_no-- 공통 값(mem_no) 결합
AS(Aliases)는 임시로 별칭 생성.(생략 가능)
ON은 두 테이블 간의 연결 조건을 지정하는 명령어. 대부분 PK 및 FK를 연결 조건으로 지정.
2-2-2 OUTER JOIN
OUTER JOIN은 두 테이블 간의 공통 값이 매칭되는 데이터뿐만 아니라 매칭 안되는 데이터도 조회하는 명령어. 즉, 공통값이 매칭 안되는 데이터도 함께 조회할 때 사용되며 종류는 총 3가지(LEFT, RIGHT, FULL)
LEFT JOIN : 왼쪽 테이블 기준 데이터 조회
RIGHT JOIN : 오른쪽 테이블 기준 데이터 조회
FULL JOIN : 양쪽 테이블 기준 데이터 조회
LEFT JOIN
-- LEFT JOIN : 왼쪽 테이블 기준 데이터 조회-- [MEMBER] 및 [ORDER] 테이블 공통 값(mem_no) 결합 + 매칭 안되는 [MEMBER] 데이터 조회SELECT*FROM [MEMBER] A -- 왼쪽 테이블LEFT JOIN [ORDER] B -- 오른쪽 테이블ONA.mem_no=B.mem_no
[MEMBER]과 [ORDER] 테이블 간의 공통 값(mem_no)이 매칭되는 데이터 뿐만 아니라 왼쪽 테이블 기준[MEMBER]으로 매칭 안 되는 데이터도 조회. -> 매칭 안되는 데이터는 모두 NULL값으로 조회.
RIGHT JOIN
-- RIGHT JOIN : 오른쪽 테이블 기준 데이터 조회-- [MEMBER] 및 [ORDER] 테이블 공통 값(mem_no) 결합 + 매칭 안되는 [ORDER] 데이터 조회SELECT*FROM [MEMBER] A -- 왼쪽 테이블RIGHT JOIN [ORDER] B -- 오른쪽 테이블ONA.mem_no=B.mem_no
[MEMBER]과 [ORDER] 테이블 간의 공통 값(mem_no)이 매칭되는 데이터 뿐만 아니라 오른쪽 테이블 기준[MEMBER]으로 매칭 안 되는 데이터도 조회. -> LEFT JOIN과 달리 회원가입 후에 주문이 가능하므로 NULL값이 조회되지 않음.
FULL JOIN
-- FULL JOIN : 양쪽 테이블 기준 데이터 조회-- [MEMBER] 및 [ORDER] 테이블 공통 값(mem_no) 결합 + 매칭 안되는 [MEMBER] 및 [ORDER] 데이터 조회SELECT*FROM [MEMBER] A -- 왼쪽 테이블
FULL JOIN [ORDER] B -- 오른쪽 테이블ONA.mem_no=B.mem_no
[MEMBER]과 [ORDER] 테이블 간의 공통 값(mem_no)이 매칭되는 데이터 뿐만 아니라 양쪽 테이블 기준[MEMBER][ORDER]으로 매칭 안 되는 데이터도 조회.
FULL JOIN은 LEFT 및 RIGHT JOIN 성질을 모두 가지고 있음.
2-2-3 OTHER(CROSS, SELF) JOIN
CROSS JOIN은 두 테이블(A, B)의 행을 결합하는 명령어 -> A 테이블에 3개의 행이 있고 B 테이블에 N개의 행이 있으면 3 X N개의 행이 조회.
SELF JOIN은 한 테이블(A)의 행과 다른 행들을 결합하는 명령어 -> A 테이블에 3개의 행이 있다면 3 X 3개의 행이 조회.
CROSS JOIN
-- CROSS JOIN : 두 테이블의 행을 결합한 데이터 조회-- [MEMBER] 행 X [ORDER] 행SELECT*FROM [MEMBER] A
CROSS JOIN [ORDER] B
WHEREA.mem_no='1000001'-- mem_no가 [MEMBER] 및 [ORDER]에도 있으므로, A.mem_no 또는 B.mem_no로 명시해야함
mem_no를 '1000001'로 필터했기 때문에 1행 X N행이 조회.
mem_no가 [MEMBER] 및 [ORDER] 테이블에 모두 있기 때문에 A.mem_no로 정확한 테이블의 열 명시.
SELF JOIN
-- SELF JOIN : 한 테이블(MEMBER)을 두 테이블(A,B)로 하여 행을 결합한 데이터 조회-- [MEMBER] 행 X [MEMBER] 행SELECT*FROM [MEMBER] A, [MEMBER] B
WHEREA.mem_no='1000001'-- mem_no가 [MEMBER]의 A,B에 있으므로, A.mem_no 또는 B.mem_no로 명시해야함
mem_no를 '1000001'로 필터했기 때문에 1행 X N행이 조회.
mem_no가 [MEMBER] A 및 [MEMBER] B 테이블에 모두 있기 때문에 A.mem_no로 정확한 테이블의 열 명시.
3. 서브 쿼리(Sub Query)
3-1 서브 쿼리란?
서브 쿼리(Sub Query)는 하나의 SQL 명령어에 포함된 SELECT 명령어.
하나의 SQL 명령어는 메인 쿼리(Main Query)라 하며, 서브 쿼리(Sub Query)는 SELECT절, FROM절, WHERE절 뒤에 위치하여 사용.
3-2 위치에 따른 서브 쿼리
서브 쿼리(Sub Query)는 주로 SELECT절, FROM절, WHERE절 뒤에 위치하여 사용.
3-2-1 SELECT절
-- SELECT절에 사용되는 서브 쿼리SELECT*
,(SELECT gender
FROM [MEMBER] B
WHEREA.mem_no=B.mem_no) AS gender
FROM [ORDER] A
SELECT절에 사용되는 서브 쿼리는 하나의 열처럼 사용되고, 이를 스칼라(Scala) 서브 쿼리라고 정의. -> 스칼라는 한번에 하나의 값만 보유할 수 있는 원자량.
JOIN의 대체 표현식이지만, 데이터의 양이 많으면 실행 속도가 느려 거의 사용 X.
3-2-2 FROM절
SELECT*FROM (
SELECT mem_no, SUM(sales_amt) AS tot_amt -- 집계함수에 대한 열 이름FROM [ORDER]
GROUP BY mem_no
) A -- 서브 쿼리에 대한 테이블명
FROM절에 사용되는 서브 쿼리는 테이블처럼 사용되며, 이를 인라인 뷰(Inline View)서브 쿼리라고 정의.
테이블처럼 사용되기 때문에 열 이름 및 테이블명을 명시.
-- FROM절에 사용되는 서브 쿼리-- [MEMBER] 및 [ORDER] 테이블 공통 값(mem_no) 결합-- 1:1 관계SELECT*FROM (
SELECT mem_no, SUM(sales_amt) AS tot_amt -- 집계함수에 대한 열 이름FROM [ORDER]
GROUP BY mem_no
) A -- 서브 쿼리에 대한 테이블명LEFT JOIN [MEMBER] B
ONA.mem_no=B.mem_no
FROM절에 사용된 서브쿼리(A)와 [MEMBER] 테이블 간의 공통 값(mem_no)이 매칭되는 데이터만 조회.
3-2-3 WHERE절
WHERE절 뒤에 위치한 쿼리는 일반 서브 쿼리로 정의. 종류는 2가지(단일, 다중).
단일 행 서브쿼리
-- WHERE절에 사용되는 서브 쿼리(단일 행 서브쿼리)-- 단일 행 : 서브 쿼리 결과가 단일 행SELECT*FROM [ORDER]
WHERE mem_no = (SELECT mem_no FROM [MEMBER] WHERE mem_no ='1000005')
-- 단일 행 확인SELECT mem_no FROM [MEMBER] WHERE mem_no ='1000005'
-- WHERE절에 사용되는 서브 쿼리(다중 행 서브쿼리)-- 다중 행 : 서브 쿼리 결과가 여러 행SELECT*FROM [ORDER]
WHERE mem_no = (SELECT mem_no FROM [MEMBER] WHERE gender ='man')
-- 다중 행 확인SELECT mem_no FROM [MEMBER] WHERE gender ='man'
WHERE절에 사용된 'IN'은 리스트(List)의 값 중 하나라도 일치하면 되는 특수 연산자.
다중 행 서브 쿼리는 결과가 여러 행이어야 함.
4. 정리
4-1 데이터 조회(SELECT)
USE EDU -- [EDU] 데이터베이스 사용.-- (1) SELECT, FROM : [ORDER] 테이블의 모든 컬럼을 조회하여라.SELECT*FROM [ORDER]
-- (2) WHERE : [shop_code]는 30 이상으로만 필터링하여라.SELECT*FROM [ORDER]
WHERE shop_code >=30-- (3) GROUP BY(+SUM 함수) : [mem_no]별 [sales_amt] 합계를 구하여라. (* SUM(sales_amt)의 컬럼명은 tot_amt)SELECT mem_no, SUM(sales_amt) AS tot_amt
FROM [ORDER]
WHERE shop_code >=30GROUP BY mem_no
-- (4) HAVING : [sales_amt] 합계가 100000 이상으로만 필터링하여라.SELECT mem_no, SUM(sales_amt) AS tot_amt
FROM [ORDER]
WHERE shop_code >=30GROUP BY mem_no
HAVINGSUM(sales_amt) >=100000-- (5) ORDER BY(+DESC) : [sales_amt] 합계가 높은 순으로 정렬하여라.SELECT mem_no, SUM(sales_amt) AS tot_amt
FROM [ORDER]
WHERE shop_code >=30GROUP BY mem_no
HAVINGSUM(sales_amt) >=100000ORDER BYSUM(sales_amt) DESC
4-2 데이터 조회(SELECT) + 결합(JOIN) + 서브 쿼리(Sub Query)
JOIN 활용
USE EDU -- [EDU] 데이터 베이스 사용.-- 데이터 조회(SELECT) + 결합(JOIN)-- (1) [ORDER] 테이블 기준으로 [MEMBER] 테이블을 LEFT JOIN 하여라.SELECT*FROM [ORDER] A
LEFT JOIN [MEMBER] B
ONA.mem_no=B.mem_no-- (2) [gender]별 [sales_amt] 합계를 구하여라.(* SUM(sales_amt)의 컬럼명은 tot_amt)SELECTB.gender, SUM(sales_amt) AS tot_amt
FROM [ORDER] A
LEFT JOIN [MEMBER] B
ONA.mem_no=B.mem_noGROUP BYB.gender-- (3) [gender], [addr]별 [sales_amt] 합계를 구하여라.(* SUM(sales_amt)의 컬럼명은 tot_amt)SELECTB.gender, B.addr, SUM(sales_amt) AS tot_amt
FROM [ORDER] A
LEFT JOIN [MEMBER] B
ONA.mem_no=B.mem_noGROUP BYB.gender, B.addr
JOIN 및 Sub Query 활용
USE EDU -- [EDU] 데이터 베이스 사용.-- 데이터 조회(SELECT) + 결합(JOIN) + 서브 쿼리(Sub Query)-- (1) [ORDER] 테이블의 [mem_no]별 [sales_amt] 합계를 구하여라.(* SUM(sales_amt)의 컬럼명은 tot_amt)SELECT mem_no, SUM(sales_amt) AS tot_amt
FROM [ORDER]
GROUP BY mem_no
-- (2) (1)을 FROM절 서브 쿼리를 사용하여. [MEMBER] 테이블을 LEFT JOIN 하여라.SELECT*FROM (
SELECT mem_no, SUM(sales_amt) AS tot_amt
FROM [ORDER]
GROUP BY mem_no
) A
LEFT JOIN [MEMBER] B
ONA.mem_no=B.mem_no-- (3) [gender], [addr]별 [tot_amt] 합계를 구하여라.(* SUM(tot_amt))의 컬럼명은 합계)SELECTB.gender, B.addr, SUM(tot_amt) AS 합계
FROM (
SELECT mem_no, SUM(sales_amt) AS tot_amt
FROM [ORDER]
GROUP BY mem_no
) A
LEFT JOIN [MEMBER] B
ONA.mem_no=B.mem_noGROUP BYB.gender, B.addr