스터디 : 데이터베이스 for beginner - 2장,8-1장

호밀빵 굽는 쿼카·2022년 1월 19일
0

NHN Cloud 인턴

목록 보기
11/48

2장 : 데이터베이스 전체 운영 맛보기

section 1. 데이터베이스 모델링

1. 정보시스템

분석-설계-구현-시험-유지보수 단계

  • 요구사항 분석
    무엇을 할지 결정
  • 설계
    시스템을 어떻게 설계할것인지 결정

2. 데이터베이스 모델링과 필수 용어

  • 데이터 베이스란?
    데이터(테이블) 저장소
  • DBMS
    데이터베이스를 관리하는 소프트웨어
  • 데이터베이스 모델링이란?
    현실세계에서 사용되는 데이터를 mysql에 어떻게 옮겨놓을지 결정하는 과정

예시를 통해 알아보자

아이디 회원이름 주소
Thomas 토마스 경기
Edward 에드워드 서울
Henry 고든 인천

제품명 가격 제조일 제조사 남은 수량
냉장고 10 2019 삼성 17
컴퓨터 20 2020 롯데 22
  • 데이터 : 토마스,컴퓨터 등 단편적 정보
  • 테이블 : 데이터 입력 위해 표형태로 만든것
  • 데이터베이스 : 테이블 저장되는 저장소 ( 쇼핑몰 데이터베이스 )
  • DBMS : 데이터베이스 관리하는 시스템 ( mysql )
  • 열(필드) : 아이디,회원이름,주소
  • 열이름 : 아이디,회원이름,주소
  • 데이터 형식 : 열의 데이터 형식 ( 문자, 숫자 )
  • 행(레코드) : 실질적 데이터, 회원테이블의 'Thomas/토마스/경기'
  • 기본키(주키) : 각 행을 구분하는 유일한 열
  • 외래키 : 두 테이블의 관계를 맺어주는 키
  • SQL : DBMS와 사람이 소통하기 위한 언어

section2. 데이터베이스 구축

1. 데이터베이스 구축 절차 요약

  1. DBMS 설치
  2. 데이터베이스 구축 절차
    1) 데이터베이스 생성
    2) 테이블 생성
    3) 데이터 입력
    4) 데이터 조회 및 활용
  3. 테이블 외 데이터베이스 개체의 활용 -> 데이터 백업 및 관리
  4. 응용 프로그램에서 구축된 데이터 활용(웹서비스/앱)

2. 데이터베이스 생성

1) workbench 실행

user : root
password : 1234

입력하면 mysql 연결
만약 오류가 발생 시 [Database]-[Connect to Databse] 선택 후 stored connection에서 local instance mysql 선택 후 위의 아이디 비번 입력해서 접속

인스턴스 : mysql 프로그램이 컴퓨터에서 활성화돼있는 서비스

workbench 화면 구성

  • 쿼리창
  • 쿼리 실행 버튼
  • 쿼리 결과 창
  • 결과 메시지 창
  • 데이터 개수
  • 쿼리 수행시간
  • 서버 관리 창
  • 데이터베이스 목록 창

2) 쇼핑몰 데이터베이스 생성

mysql에서는 스키마=데이터베이스

workbench [SCHEMAS] > [Create Schema] > 이름입력

3) 테이블 생성

  1. 개체 이름 정하기

    개체이름은 영문 사용

  2. 회원테이블 만들기
  • shopdb 선택 > tables 선택 > create table > memberTBL(회원테이블) 입력 > 열 이름 바로 아래 더블클릭 해 내용 입력
  • PK 에 체크 표시해 아이디(memberID) 열을 기본키로 설정
  • apply 클릭
  1. 제품테이블 만들기
  2. 생성한 테이블 확인하기

4) 데이터 입력

  1. 회원테이블의 데이터 입력하기
  2. 제품테이블의 데이터 입력하기

5) 데이터 활용

  1. 쿼리 창 열기
  2. select문 작성하기
    SELECT 열이름 FROM 테이블이름 WHERE 조건;
    SELECT * FROM memberTBL;
    SELECT * FROM memberTBL WHERE memberName='토마스';
  3. sql문으로 새로운 테이블 생성하기
    CREATE TABLE "my testTBL" (id INT);
  4. 테이블 삭제하기
    DROP TABLE "my TestTBL";

section3. 데이터베이스 개체 활용

1. 데이터베이스 개체의 종류

인덱스, 뷰, 스토어드 프로시저, 트리거, 함수, 커서

2. 인덱스

데이터베이스 튜닝이란?

데이털베이스의 성능을 향상하거나 응답하는 시간을 단축시키는 것입니다. 튜닝 시 쿼리에 대한 응답을 줄이기위해 가장 집중적으로 보는 부분 중 하나가 인덱스.

1) 적정량의 데이터가 있는 테이블 생성

CREATE TABLE indexTBL(first_name varchar(14), last_name varchar(16), hire_date date);
INSERT INTO indexTBL
	SELECT first_name, last_name, hire_date
    	FROM employees.employees
    	LIMIT 500;
SELECT * FROM indexTBL;

2) 인덱스가 없는 상태에서 쿼리 작동 확인하기

  • SELECT * FROM indexTBL WHERE first_name='Mary';
  • 잠시 후 결과가 나오면 [Execution Plan]을 클릭해 실행 계획 확인
  • 'Full Table Scan'의 의미 : 인덱스를 사용하지 않고 테이블 전체를 검색했다는 뜻
    • 전체 테이블 스캔 : 모든 행 데이터 읽어보는 것
    • 대량 데이터가 들어있는데이터베이스에서 검색한다면 시간이 많이 걸리는 것은 물론 시스템에 과부하 초래

3) 인덱스 생성 후 쿼리 작동 확인하기

CREATE INDEX idx_indexTBL_firstname ON indexTBL(first_name);
SELECT * FROM indexTBL WHERE first_name='Mary';
  • Non-Unique key Lookup = 인덱스를 사용했다는 의미
  • 책의 찾아보기가 있을 때 먼저 찾아보기에서 특정 단어를 찾아보고 그 페이지를 펴서 검색하는 것과 같음

3. 뷰

뷰 : 가상의 테이블, 실체가 없고 진짜 테이블에 연결된 개념

  • 쇼핑몰 운영 시, 회원의 주소를 대량으로 변경하는 작업 필요하다고 가정

    🗣 아르바이트생을 고용해 회원의 정보 가운데 주소만 변경하는 일을 시키고 싶습니다!

  • 아르바이트생에게 회원테이블을 사용할 권한을 준다면 아르바이트생이 회원의 주소 외 중요 개인 정보를 열람하게 됨
  • 이때, 주민등록번호 등의 중요한 정보를 제외하고 아이디와 주소만 있는 테이블을 다시 생성한 후 데이터를 입력
    => 데이터 다시 입력하는 소모적 작업 + 두 테이블 존재하게 됨(문제)
  • 위의 문제들을 해결하기 위해 뷰 사용
    => 아이디와 주소만 있는 뷰를 생성, 뷰는 실체가 있는 것이 아니라 회원 테이블에 링크된 개념이므로 실제 데이터는 회원 테이블에만 존재하고 데이터의 중복이 발생하지 않음. 아르바이트생에게 뷰 접근 권한만 줌.

1) 현재 데이터베이스를 ShopDB로 변경하기

2) 뷰 생성하기

회원이름과 주소만 있는 뷰 생성

CREATE VIEW uv_memberTBL
AS
SELECT memberName, memberAddress FROM memberTBL;

3) 뷰 조회하기

아르바이트 생은 뷰인지 테이블인지 알 필요도 없이 다른 테이블과 동일하게 사용가능=> 주소 변경 작업 맡길 수 있음

SELECT * FROM uv_memberTBL;

4. 스토어드 프로시저

스토어드 프로시저 : mysql에서 제공하는 프로그래밍 기능, sql문을 하나로 묶어 편리하게 사용하는 기능

1) 2개의 쿼리를 각각 실행

SELECT * FROM memberTBL WHERE memberName='토마스';
SELECT * FROM productTBL WHERE productName='냉장고';

2) 2개의 쿼리를 하나의 스토어드 프로시저로 만들기

DELIMITER//
CREATE PROCEDURE myProc()
BEGIN
	SELECT * FROM memberTBL WHERE memberName='토마스';
    SELECT * FROM productTBL WHERtNameE='냉장고';
END//
DELIMITER;

SQL문 뒤의 //(구문문자)는 기존의 세미콜론을 대신한다는 의미

3) CALL myProc() 로 스토어드 프로시저 실행만 하면 됨


5. 트리거

  • 테이블에 부착돼 테이블에 INSERT, UPDATE, DELETE 작업이 발생하면 실행되는 코드
  • 회원 테이블에서 삭제 작업이 일어날 때마다 다른 곳에 그 데이터를 '자동으로'저장하는 기능
  • 트리거를 작성하면 사용자는 행 데이터를 삭제하기 전에 다른 곳에 저장하는 업무 부담에서 벗어남

1) 데이터를 삽입,수정,삭제하는 SQL문 작성

INSERT INTO memberTBL VALUES('Soccer','흥민','서울시');
UDATE memberTBL SET memberAddress='서울시' WHERE memberName='흥민';
DELETE FROM memberTBL WHERE memberName='흥민';

위의 문제를 해결하기 위해

2) 다른 테이블에 삭제된 데이터와 삭제된 날짜 기록하기

# SQL문 생성
CREATE TABLE deleteMemberTBL(
memberID char(8),
memberName char(5),
memberAddress char(20),
deleteDate date
);
# 트리거 생성
# 삭제된 행이 deletedMemberTBL 에 저장됨
DELIMITER //
CREATE TRIGGER trg_deleteMemberTBL
	AFTER DELETE
    	ON memberTBL
    	FOR EACH ROW
BEGIN
	INSERT INTO deletedMemberTBL
    		VALUES(OLD.memberID, OLD.memberName, OLD.memberAddress, CURDATE());
END //
DELIMITER;

3) 회원 테이블의 데이터 삭제 후 삭제된 데이터가 백업 테이블에 들어가는지 확인



8-1장 : 조인

조인(Join) 이란?

2개 이상의 테이블을 묶어서 하나의 결과 테이블을 만드는 것

section 1 : 조인

1. 조인의 개요

🙎 조인을 공부해보기 이전에 일대다 테이블 구조를 살펴봅시다. 👨‍👩‍👧‍👦

Q. 데이터베이스가 데이터를 여러개의 테이블에 나누어 저장하는 이유?

A. 데이터의 중복저장,저장공간의 낭비 등을 피하고 데이터 무결성을 보장하기 위해서

나누어져 있는 테이블은 서로 관계를 맺고 있는데 [그림 8-1] 의 회원테이블과 구매테이블이 맺고 있는 '일대다' 관계이다. '일대다' 관계란, 한쪽 테이블에는 하나의 값만 존재하고 그 값과 대응하는 다른 쪽 테이블의 값은 여러개인 관계를 말한다.

  • [그림 8-1] 의 회원테이블을 보면 강호동은 회원 가입 시 'KHD'이라는 아이디를 생성했다. 강호동이 생성 한 'KHD' 라는 아이디는 다른사람이 사용할 수 없다. 이렇게 하나만 존재하는 것이 '일대다' 관계에서 '일' 에 해당한다.
  • [그림 8-1] 에서 구매테이블의 아이디 열을 회원 테이블과 동일하게 기본키로 지정하면 KHD라는 아이디를 가진 사람, 즉 강호동은 물건을 한번 구매한 후 두번 다시 물건을 구매할 수 없다. 왜냐하면, 기본키의 값은 하나이기 때문이다. 따라서, 구매 테이블의 아이디 열은 한 회원이 여러 개의 물건을 살 수 있도록 설정해야 한다.
  • 해결법 : '일'에 해당하는 회원 테이블의 아이디는 기본키로 지정, '다'에 해당하는 구매 테이블의 아이디는 기본키와 관련이 있는 외래키(FK)로 지정한다.

일상생활에서의 일대다 관계

  • 급여 : 기업의 직원테이블과 급여테이블
  • 학점 : 학교의 학생테이블과 학점테이블


조인의 종류

  1. 내부 조인
  2. 외부 조인
  3. 상호 조인
  4. 자체 조인

2. 내부 조인

2.1.두 테이블의 내부 조인

1. 구매 테이블에서 KYM이라는 아이디를 가진 회원이 구매한 물건을 발송하기

  • 방법 : 회원테이블과 조인한 후 아이디가 KYM인 사람 검색
  • 순서
    1) 구매 테이블의 회원 아이디(buyTBL.userID)인 KYM 추출
    2) KYM과 동일한 값을 회원 테이블의 아이디에서(userTBL.userID)에서 검색
    3) 아이디 KYM 찾으면 구매 테이블과 회원 테이블의 두행을 결합(조인)
USE cookDB;
SELECT *
	FROM buyTBL
    	    INNER JOIN userTBL
    		ON buyTBL.userID=userTBL.userID
  	WHERE buyTBL.userID='KYM';



2. 마지막 행인 WHERE buyTBL.userID='KYM';을 생략하면 구매 테이블의 모든 행에 대해 동일한 방식으로 회원 테이블과 결합

USE cookDB;
SELECT *
	FROM buyTBL
    	    INNER JOIN userTBL
    		ON buyTBL.userID=userTBL.userID



3. 아이디,이름,구매물품,주소,연락처 등 필요한 열만 추출해보기

SELECT userID, userName, prodName, addr, CONCAT(mobile1, mobile2) AS '연락처'
	FROM buyTML
    	    INNER JOIN userTBL
        	ON buyTBML.userID=userTBL.userID;

❗️ 오류 발생
Error code: Column 'userid' in field list is ambiguous

💡 해결
열이름 userID가 불확실하다는 오류메세지는 userID는 두 테이블 모두 들어있는데 어느 테이블의 userID를 추출할지 명시하지 않아 오류가 발생한 것. 이럴 때는 어느 테이블의 userID를 추출할 건지 선택

# 구매테이블(buyTBL)을 기준으로 회원테이블(userTBL)을 조인하는것이므로 구매 테이블의 userID를 명시
SELECT buyTBL.userID, userName, prodName, addr, CONCAT(mobile1, mobile2) AS '연락처'
	FROM buyTML
    	    INNER JOIN userTBL
        	ON buyTBML.userID=userTBL.userID;
# 결과 : userID, userName, prodName, addr, mobile 등의 원하는 속성만 출력



4. 코드를 좀 더 명확하게 하기 위해 모두 '테이블이름.열이름' 형식으로 작성해보기

SELECT buyTBL.userID, userTBL.userName, buyTBL.prodName, userTBL.addr,
		CONCAT(userTBL.mobile1, userTBL.mobile2) AS '연락처'
FROM buyTBL
	INNER JOIN userTBL
    		ON buyTBL.userID=userTBL.userID;

하지만 코드가 길어져서 복잡해보인다. 별칭을 사용해서 보다 간단하게 작성해보자. 별칭은 FROM절에 나오는 테이블 이름 뒤에 별칭을 붙이면 된다.

SELECT B.userID, U.userName, B.prodName, U.addr,
		CONCAT(U.mobile1, U.mobile2) AS '연락처'
FROM buyTBL B
	INNER JOIN userTBL U
    		ON B.userID=U.userID;

KYM이라는 아이디를 가진 회원이 구매한 물건과 회원정보를 조인하되, 아이디,이름,물품,주소,연락처만 출력되게 하고 코드도 간결하게 작성해보자(구매 테이블 기준 조회)

SELECT B.userID, U.userName, B.prodName, U.addr, CONCAT(U.mobile1, U.mobile2) AS '연락처'
FROM buyTBL B
	INNER JOIN userTBL U
    		ON B.userID=U.userID
WHERE B.userID='KYM';
userIduserNameprodNameaddr연락처
KYM김용만모니터서울0104444444

🔼 결과 테이블은 동일 🔽

KYM이라는 아이디를 가진 회원이 구매한 물건과 회원정보를 조인하되, 아이디,이름,물품,주소,연락처만 출력되게 하고 코드도 간결하게 작성해보자(회원 테이블 기준 조회)

SELECT U.userID, U.userName, B.prodName, U.addr, CONCAT(U.mobile1, U.mobile2) AS '연락처'
FROM userTBL U
	INNER JOIN buyTBL B
    		ON U.userID=B.userID
WHERE B.userID='KYM';


5. 전체 회원이 구매한 목록을 모두 출력해보기

SELECT U.userID, U.userName, B.prodName, U.addr, CONCAT(U.mobile1, U.mobile2) AS '연락처'
FROM userTBL U
	INNER JOIN buyTBL B
    		ON U.userID=B.userID
# 결과를 보기 쉽게 회원 아이디순으로 정렬
ORDER BY U.userID;


문제가 없어보이지만 원래 의도한 '전체 회원'이 아니라 '구매한 기록이 있는 회원'을 출력한 것. 이처럼 구매한 회원의 기록뿐만 아니라 구매하지 않은 회원의 이름,주소 등도 출력하고자 할 때 사용하는 조인 방식은 외부조인이다.
🧐 외부조인 : 양쪽 테이블에 내용이 있는 것은 물론이고 한쪽 테이블에만 내용이 있어도 조인하는 방식



6. 내부조인이 유용하게 사용되는 예
쇼핑몰에서 한번이라도 구매한 기록이 있는 우수회원에게 감사의 안내문을 발송해보자

# 중복제거 키워드 DISTINCT를 통한 sql문
SELECT DISTINCT U.userID, U.userName, U.addr
	FROM userTBL U
    	INNER JOIN buyTBL B
        	ON U.userID=B.userID
ORDER BY U.userID;
userIduserNameaddr
KHD강호동경북
KJD김제동경남
KYM김용만서울
LHJ이휘재경기
PSH박수홍서울

🔼 결과 테이블은 동일 🔽

# 서브쿼리 안의 조건유무를 검사하는 EXISTS 키워드를 통한 sql문
SELECT U.userID, U.userName, U.addr
	FROM userTBL U
    	WHERE EXISTS(
    		SELECT *
        	FROM buyTBL B
        	WHERE U.userID=B.userID);


2.2.세 테이블의 내부 조인

학교 동아리를 생각해보자. 한 학생은 여러 개의 동아리에 가입해서 활동할 수 있고, 하나의 동아리에는 여러 학생이 가입할 수 있다. 따라서 학생 테이블과 동아리 테이블은 다대다 관계이다.
다대다 관계는 물리적으로 구성하려면 두 테이블 사이에 연결 테이블을 두고 연결 테이블과 두 테이블이 일대다 관계를 맺도록 구성해야한다.

  • 테이블의 복잡성을 없애기 위해 학생의 이름과 동아리명을 기본키로 설정
  • 실제로는 학생이름을 기본키로 설정하지 않는다! => 동명이인이 있을 수도 있기 때문에 개개인을 구분할 수 없음
  • 구조를 보면, 학생 테이블과 동아리 테이블은 서로 직접적인 관련이 없는데 중간에 학생_동아리 테이블을 두어 두 테이블의 관계를 맺음
  1. 테이블 생성
  2. 조인하기
SELECT S.stdName, S.addr, C.clubName, C.roomNo
	FROM stdTBL S
    	INNER JOIN stdclubTBL SC
    		ON S.stdName=SC.stdName
        INNER JOIN clubTBL C
        	ON SC.clubName=C.clubName
ORDER BY S.stdName;

학생테이블과 학생동아리 테이블을 조인 --> 학생동아리 테이블과 동아리 테이블을 조인



3. 외부 조인

🧐 외부조인

  • 양쪽 테이블에 내용이 있는 것은 물론이고 한쪽 테이블에만 내용이 있어도 조인하는 방식
  • 조인 조건을 만족하지 않는 행까지 포함해 출력하는 조인
SELECT < 이름>
FROM <첫번째 테이블(LEFT 테이블)>
	<LEFT | RIGHT> OUTER JOIN <두번째 테이블(RIGHT 테이블)>
    ON <조인될 조건>
[WHERE 검색조건];

1) 전체회원의 구매 기록을 출력하되 구매 기록이 없는 회원도 출력해보는 예시를 통해 알아보자.

USE cookDB;
SELECT U.userID, U.userName, B.prodName, U.addr, CONCAT(U.mobile1, U.mobile2) AS '연락처'
	FROM userTBL U
    	LEFT OUTER JOIN buyTBL B
    	ON U.userID=B.userID
ORDER BY U.userID;


🔼 결과 테이블은 동일 🔽

2) LEFT OUTER JOIN은 결과가 조인 조건에 해당하지 않더라도 왼쪽 테이블(userTBLE)의 모든 행을 출력한다. RIGHT OUTER JOIN을 사용하려면 왼쪽 테이블과 오른쪽 테이블의 위치만 변경

USE cookDB;
SELECT U.userID, U.userName, B.prodName, U.addr, CONCAT(U.mobile1, U.mobile2) AS '연락처'
	FROM buyTBL B
    	RIGHT OUTER JOIN userTBL U
    	ON U.userID=B.userID
ORDER BY U.userID;

3) WHERE 검색조건을 추가해서 물건을 한 번도 구매한 적 없는 회원의 목록을 출력해보자.

SELECT U.userID, U.userName, B.prodName, U.addr, CONCAT(U.mobile1, U.mobile2) AS '연락처'
	FROM userTBL U
    	LEFT OUTER JOIN buyTBL B
    	ON U.userID=B.userID
WHERE B.prodName IS NULL
ORDER BY U.userID;

4) 학생,동아리,학생_동아리 테이블을 통해 왼쪽/오른쪽 외부 조인하기

동아리에 가입하지 않은 학생도 출력되는 쿼리문=모든 학생 출력

USE cookDB;
SELECT S.stdName, S.addr, C.clubName, C.roomNo,
	FROM stdTBL S
    	LEFT OUTER JOIN stdclubTBL SC
        ON S.stdName=SC.stdName
        LEFT OUTER JOIN clubTBL C
        ON SC.clubName=C.clubName  
ORDER BY S.stdName;

동아리를 기준으로 가입 학생을 출력하되, 가입 학생이 한 명도 없는 동아리도 출력하는 쿼리문=모든 동아리 출력

USE cookDB;
SELECT C.clubName, C.roomNo, S.stdName, S.addr
	FROM stdTBL S
    	LEFT OUTER JOIN stdclubTBL SC
        ON SC.stdName=S.stdName
        RIGHT OUTER JOIN clubTBL C
        ON SC.clubName=C.clubName  
ORDER BY C.clubName;
  • 결과가 왼쪽 테이블 전체 데이터 대상이라면 left를 ,오른쪽 테이블의 전체 데이터가 대상이라면 right를 사용
  • 세 테이블을 동아리를 기준으로 조인해야하므로 하나는 LEFT, 하나는 RIGHT

5) 완전 외부 조인을 한 것과 같은 효과

UNION을 사용하면

USE cookDB;
SELECT S.stdName, S.addr, C.clubName, C.roomNo,
	FROM stdTBL S
    	LEFT OUTER JOIN stdclubTBL SC
        ON S.stdName=SC.stdName
        LEFT OUTER JOIN clubTBL C
        ON SC.clubName=C.clubName  
UNION
SELECT C.clubName, C.roomNo, S.stdName, S.addr
	FROM stdTBL S
    	LEFT OUTER JOIN stdclubTBL SC
        ON SC.stdName=S.stdName
        RIGHT OUTER JOIN clubTBL C
        ON SC.clubName=C.clubName  

동아리에 가입하지 않은 학생도 출력하고, 학생이 한 명도 없는 동아리도 출력하는 쿼리문 작성 가능



4. 상호 조인

상호조인이란?

  • 한쪽 테이블의 모든 행과 다른 쪽 테이블의 모든 행을 조인하는 것
  • 카티션곱이라고도 함
USE cookDB;
SELECT *
FROM buyTBL
CROSS JOIN userTBL;

상호조인 결과 테이블의 행수는?

두 테이블의 행수를 곱한 값

상호조인의 장점

  • 테스트로 사용할 많은 용량의 데이터를 생성할 때 유용하다.
  • 예를 들어, employees DB에서 employees테이블(30만)과 titles테이블(44만)을 상호조인하면 약 1300억건(30만x44만)의 데이터를 생성할 수 있다.
  • 실제로 많은 용량의 데이터 생성되면 시스템 다운될 수 있으니 COUNT(*)함수로 상호조인한 결과의 개수만 알아보기

상호조인을 하는 다른 방법

USE cookDB;
SELECT *
FROM buyTBL, userTBL;

CROSS JOIN을 쓰지 않고 테이블을 나열해도 되지만, 호환성 문제로 이는 권장하지 않습니다.



5. 자체 조인

자체조인이란?

  • 자기 자신과 자기 자신을 조인하는 것
  • 별도의 구문이 있는 것은 아님

조직도 예제를 통해 알아보자

  • 이부장은 직원이므로 직원 이름 열에 존재
  • 이부장은 우대리와 지사원의 상관이므로 상관 이름 열에 존재
  • 우대리 상관의 구내 번호를 알고싶다면, 직원 이름 열과 상관 이름 열을 조인

1) 조직도 테이블 만들기
2) 조직도 테이블 데이터 입력
3) 자체 조인하기

# emp: 직원이름, manager: 직속상관이름, empTel: 연락처
SELECT A.emp AS '부하직원', B.emp AS '직속상관', B.empTel AS '직속상관연락처'
FROM empTBL A
INNER JOIN empTBL B
# 직원의 상관이름(A.manager)과 직원의 이름(B.emp)이 같다면
ON A.manager=B.emp
WHERE A.emp='우대리';
부하직원직속상관직속상관연락처
우대리이부장2222-2

직속상관이름과 직속상관연락처를 알 수 있음



6. UNION/UNION ALL

UNION : 두 쿼리의 결과를 행으로 합치는 연산자

예제를 통해 알아봅시다.

stdTBML

stdNameaddr
강호동경북
김제동경남
김용만서울
이휘재경기
박수홍서울

clubTBL

clubNameroomNo
수영101호
바둑102호
축구103호
봉사104호
USE cookDB;
SELECT stdName, addr FROM stdTBL
UNION
SELECT clubName, roomNO FROM clubTBL;

🔽

UNION한 결과

stdNameaddr
강호동경북
김제동경남
김용만서울
이휘재경기
박수홍서울
수영101호
바둑102호
축구103호
봉사104호
  • SELECT문장을 수행했을 때 열의 개수가 같아야함
  • 데이터 형식도 각 열 단위로 같거나 서로 호환되는 형식
  • UNION 연산을 수행한 결과 열 이름은 문장 1의 열이름을 따름
  • 중복된 열 제거, 데이터 정렬해서 출력
  • 중복된 열까지 모두 출력하려면 UNION ALL 사용

7. NOT IN/IN

NOT IN : 첫번째 쿼리의 결과 중 두 번째 쿼리에 해당하는 것을 제외하고 출력하는 연산자

cookDB의 사용자를 모두 출력하되 전화번호가 없는 사람을 제외하는 예제

SELECT userName, CONCAT(mobile1, '-', mobile2) AS '전화번호' FROM userTBL
WHERE userName NOT IN (SELECT userName FROM userTBL WHERE mobile1 IS NULL);

IN : NOT IN과 반대로 첫번째 쿼리의 결과 중에서 두 번째 쿼리에 해당되는 것만 조회하는 연산자

cookDB의 사용자를 모두 출력하되 전화번호가 없는 사람만 출력하는 예제

SELECT userName, CONCAT(mobile1, '-', mobile2) AS '전화번호' FROM userTBL
WHERE userName IN (SELECT userName FROM userTBL WHERE mobile1 IS NULL);


실습 진행한 모습!

참고링크

조인을 연습하기 좋은 블로그

profile
열심히 굽고 있어요🍞

1개의 댓글

comment-user-thumbnail
2022년 1월 19일

다했다..! 얏호

답글 달기