2022.12.19 - [데이터베이스/0 + SQL] - [패스트캠퍼스] 2. SQL 기초1
[패스트캠퍼스] 2. SQL 기초1
SQL 기초 조건에 맞는 데이터 가져오기 WHERE WHERE [조건식] 형식으로 사용 WHERE 절이 TRUE 가 되는 행만 선택 SELECT [컬럼명] FROM [테이블명] WHERE [조건식]; MySQL에서는 TRUE 를 1로 표현, FALSE 는 0으로 표
howisitgo1ng.tistory.com
SQL 기초2
![](https://blog.kakaocdn.net/dn/oGZol/btrUwsifK6I/6k3nMMKG9Nz3R99FThHxiK/img.png)
규칙 만들기
IF
IF(조건식, 참결과, 거짓결과)
형식으로 사용- 주로
SELECT
절에 사용하는 함수 - 결과 값을 새로운 컬럼으로 반환
SELECT name,
IF(attack >= 60, 'strong', 'weak') AS attack_class
FROM mypokemon
;
IFNULL
- 데이터가
NULL
인지 아닌지 확인해NULL
이라면 새로운 값을 반환 IFNULL([컬럼명], NULL일 때 값)
형식으로 사용- 해당 컬럼의 값이
NULL
인 행에서NULL
일 때 값을 반환 - 주로
SELECT
절에 사용하는 함수 - 결과 값을 새로운 컬럼으로 반환
SELECT name,
IFNULL(name, 'unknown') AS full_name
FROM mypokemon
;
CASE
- 조건을 여러 개 만들 때 사용하는 문법
형식1
CASE
WHEN 조건식1 THEN 결과값1
WHEN 조건식2 THEN 결과값2
ELSE 결과값3
END
형식2
CASE[컬럼명]
WHEN 조건값1 THEN 결과값1
WHEN 조건값2 THEN 결과값2
ELSE 결과값3
END
- 주로
SELECT
절에 사용하는 함수 - 결과 값을 새로운 컬럼으로 반환
ELSE
문장 생략 시NULL
값을 반환
SELECT name,
CASE
WHEN attack >= 100 THEN 'very_strong'
WHEN attack >= 60 THEN 'strong'
ELSE 'weak'
END AS attack_class
FROM mypokemon
;
SELECT name,
CASE type
WHEN 'bug' THEN 'grass'
WHEN 'electric' THEN 'water'
WHEN 'grass' THEN 'bug'
END AS rival_type
FROM mypokemon
;
CREATE FUNCTION
원하는 함수 직접 만들기!
CREATE FUNCTION [함수명]([입력값 이름] [데이터 타입], ...)
RETURNS [데이터 타입] -- 결과값 데이터 타입
BEGIN
DECLARE [임시값명] [데이터타입];
SET [임시값명] = [입력값명];
쿼리;
RETURN 결과값
END
getAbility(attack INT, defense INT)
함수를 만들어 보자!
SET GLOBAL log_bin_trust_function_creators = 1;
DELIMITER $$
CREATE FUNCTION getAbility(attack INT, defense INT)
RETURNS INT
BEGIN
DECLARE a INT;
DECLARE b INT;
DECLARE ability INT;
SET a = attack;
SET b = defense;
SELECT a + b INTO ability; -- 쿼리
RETURN ability;
END $$
DELIMITER ;
실습
함수 만들기를 배웠으면 실습을 통해 해당 내용을 이해했는지 다시한번 점검해 봅시다!
- 문제
공격력과 방어력의 합이 120보다 크면very strong
, 90보다크면strong
, 모두 해당 되지 않으면not strong
을 반환하는 함수isStrong
을 만들고 사용해주세요.
조건1:attack
과defense
를 입력값으로 사용
조건2: 결과값 데이터 타입은VARCHAR(20)
사용
DELIMITER $$
CREATE FUNCTION isStrong(attack INT, defense INT)
RETURNS VARCHAR(20)
BEGIN
DECLARE isstrong VARCHAR(20);
DECLARE sum INT;
SET sum = attack + defense;
SELECT
CASE
WHEN sum > 120 THEN 'very strong'
WHEN sum > 90 THEN 'strong'
ELSE 'not strong'
END
INTO isstrong;
RETURN isstrong;
END $$
DELIMITER ;
테이블 합치기(JOIN)
- 같은 의미를 가지는 컬럼의 값을 기준으로 테이블을 합칠 때 사용하는 키워드
- 주로 FK를 이용하여 데이터를 합침
- 데이터가 더 많아짐(뻥튀기!)
SELECT [컬럼명]
FROM [테이블명1]
조인방식 키워드 JOIN [테이블명2]
ON [테이블명1].[컬럼명1] = [테이블명2].[컬럼명2]
WHERE 조건식
;
INNER JOIN
![](https://blog.kakaocdn.net/dn/DMHNB/btrUGHdSYAJ/TWtnfg2farmjk4cqPT6k40/img.png)
SELECT *
FROM mypokemon
INNER JOIN ability
ON mypokemon.number = ability.number
;
LEFT JOIN, RIGHT JOIN
![](https://blog.kakaocdn.net/dn/uZNfh/btrUxfpFyU6/QIw1j1m512VgJ3NpsCk7L0/img.png)
SELECT *
FROM mypokemon
LEFT JOIN ability
ON mypokemon.number = ability.number
;
![](https://blog.kakaocdn.net/dn/T3OgR/btrUzkYkpc1/qowRg4my34zmlK6VkAxHKK/img.png)
![](https://blog.kakaocdn.net/dn/b5VHKF/btrUGqpCTsP/8kYUjN6agGQnyG1n3o5XTk/img.png)
SELECT *
FROM mypokemon
RIGHT JOIN ability
ON mypokemon.number = ability.number
;
![](https://blog.kakaocdn.net/dn/cnbFxj/btrUIfHYFzL/KXysiZQ3M2hEYilhZwKHp1/img.png)
![](https://blog.kakaocdn.net/dn/cPzEcj/btrUwo8fvqr/9F2a89czbbaXZnnrhaE6Ik/img.png)
OUTER JOIN
MySQL
키워드에 없음 😭LEFT
+RIGHT JOIN
의 결과를 합침(UNION
)UNION
은 두 쿼리의 결과를 중복을 제외하고 합쳐서 보여주는 집합 연산자
SELECT [컬럼명]
FROM [테이블명1]
LEFT JOIN [테이블명2]
ON [테이블명1].[컬럼명1] = [테이블명2].[테이블명2]
UNION
SELECT [컬럼명]
FROM [테이블명1]
RIGHT JOIN [테이블명2]
ON [테이블명1].[컬럼명1] = [테이블명2].[테이블명2]
;
![](https://blog.kakaocdn.net/dn/X1NUd/btrUGIcO4Cc/ymQcuMP5Kvpc9YDDC7OoJ1/img.png)
![](https://blog.kakaocdn.net/dn/bOOuEw/btrUyh1QIdC/WwmH2sFhcYXXRZwFtS7k70/img.png)
SELECT *
FROM mypokemon
LEFT JOIN ability
ON mypokemon.number = ability.number
UNION
SELECT *
FROM mypokemon
RIGHT JOIN ability
ON mypokemon.number = ability.number
![](https://blog.kakaocdn.net/dn/cwf4PH/btrUEwRar6d/GLnaHdL73oRPcrKqDp1lS0/img.png)
![](https://blog.kakaocdn.net/dn/yXIyQ/btrUwtuGAHo/wGDSunUK5vKCIbVY7apZlk/img.png)
CROSS JOIN
* 두 테이블에 있는 모든 값을 각각 합치기
![](https://blog.kakaocdn.net/dn/b0muPl/btrUE5MPVy3/BgmjyGfPvwHXK5EWgevnjk/img.png)
SELECT [컬럼명]
FROM [테이블명1]
CROSS JOIN [테이블명2] -- ON 키워드가 없어도 됨
WHERE 조건식
;
SELECT *
FROM mypokemon
CROSS JOIN ability
;
모든 행이 합쳐진다….!
![](https://blog.kakaocdn.net/dn/oogcJ/btrUImmJycU/shu4jUpWpG3iWCZJXlKAh1/img.png)
![](https://blog.kakaocdn.net/dn/FjFPr/btrUAcMs8ba/ig2WeUquNvroJM8W9k6l6k/img.png)
![](https://blog.kakaocdn.net/dn/b9CWRL/btrUIgz6BdM/x7P1UuSP6jeTqYL1mIPu60/img.png)
SELF JOIN
- 같은 테이블에 있는 값 합치기
![](https://blog.kakaocdn.net/dn/cCszv3/btrUvVEWBZo/K29lBK8Z3LvJcFVr30IVi0/img.png)
SELECT [컬럼명]
FROM [테이블명1] AS T1
INNER JOIN [테이블명2] AS T2
ON T1.[컬럼명1] = T2.[컬럼명2]
WHERE 조건식
;
SELECT *
FROM mypokemon AS t1
INNER JOIN mypokemon AS t2
ON t1.number = t2.number
;
![](https://blog.kakaocdn.net/dn/EMVXu/btrUHOqeWjg/UAKr0aeGSk5sKa7Fzvpdhk/img.png)
![](https://blog.kakaocdn.net/dn/bjAyRl/btrUGIjz2bp/BndpHtLNGQIKx76XOLbk8K/img.png)
실습
포켓몬고 DBA
로 일한지 어느덧 3개월차
가 된 당신에게 다음과 같은 업무가 주어졌습니다!
1. 포켓몬 테이블과 능력치 테이블을 합쳐서 포켓몬 이름, 공격력, 방어력을 한번에 가져와 주세요.
이 때, 포켓몬 테이블에 있는 모든 포켓몬의 데이터를 가져와 주세요.
만약, 포켓몬의 능력치 데이터를 구할 수 없다면, NULL로 가져와 주세요.
2. 포켓몬 테이블과 능력치 테이블을 합쳐서 포켓몬 번호와 이름을 한번에 가져와 주세요.
이 때, 능력치 테이블에 있는 모든 포켓몬의 데이터를 가져와 주세요.
만약 포켓몬의 이름 데이터를 구할 수 없다면, NULL로 가져와 주세요.
- 동일한 이름을 가지는 컬럼이 있다면
SELECT
해 올때, 어느 테이블에서 합쳐진 컬럼을 가져올 것인지 명시해 줘야함.mypokemon.number
또는ability.number
![](https://blog.kakaocdn.net/dn/UxZ4c/btrUwplLmYI/RWN3KtclkLOcu2Rj5D1Kc1/img.png)
/*
1. 포켓몬 테이블과 능력치 테이블을 합쳐서 포켓몬 이름, 공격력, 방어력을 한번에 가져와 주세요.
이 때, 포켓몬 테이블에 있는 모든 포켓몬의 데이터를 가져와 주세요.
만약, 포켓몬의 능력치 데이터를 구할 수 없다면, NULL로 가져와 주세요.
*/
SELECT m.name, a.attack, a.defense
FROM mypokemon m
LEFT JOIN ability a
ON m.`number` = a.`number`
;
/*
2. 포켓몬 테이블과 능력치 테이블을 합쳐서 포켓몬 번호와 이름을 한번에 가져와 주세요.
이 때, 능력치 테이블에 있는 모든 포켓몬의 데이터를 가져와 주세요.
만약 포켓몬의 이름 데이터를 구할 수 없다면, NULL로 가져와 주세요.
*/
SELECT a.`number`, m.name
FROM mypokemon m
RIGHT JOIN ability a
ON m.`number` = a.`number`
;
여러 테이블 한번에 다루기
합집합(UNION, UNION ALL)
UINON
은 동일한 값은 제외하여 조회(전체가 동일해야함, 하나라도 다르면 다른것으로 인지)UNION ALL
은 동일한 값도 포함하여 조회[쿼리1] UNION [쿼리2]
또는[쿼리1] UNION ALL [쿼리2]
형식으로 사용쿼리1
과쿼리2
의 결과 값을 합쳐서 보여줌쿼리1
과쿼리2
의 결과 값의 갯수가 동일해야 함- 다를 경우 에러 발생
ORDER BY
는 쿼리 가장 마지막에 작성가능쿼리1
에서 가져온 컬럼으로만 가능
![](https://blog.kakaocdn.net/dn/UXCw9/btrUBbGOY8B/fzVYZ1NYyMDj94A7tPwD2k/img.png)
SELECT [컬럼명]
FROM [테이블1명]
UNION
SELECT [컬럼명]
FROM [테이블2명]
;
SELECT [컬럼명]
FROM [테이블1명]
UNION ALL
SELECT [컬럼명]
FROM [테이블2명]
;
교집합(INTERSECT), 차집합(MINUS)
MySQL
에는 두 표현이 존재하지 않음JOIN
을 사용하여 해결!
- 같은 이름을 가지는 컬럼이 있다면,
[테이블명].[컬럼명]
형식으로 조회
![](https://blog.kakaocdn.net/dn/ejoE9A/btrUxeEnuDH/cI3wLeqOV9ECkZYBZTMUc1/img.png)
교집합
- 교집합을 확인 하고 싶은 컬럼은 모두 다 기준으로 두고 합쳐 줘야 함
SELECT [컬럼명] FROM [테이블1명] AS A INNER JOIN [테이블2명] AS B ON A.[컬럼1명] = B.[컬럼1명] AND ... AND A.[컬럼n명] = B.[컬럼n명] ;
차집합
- A 교집합 B의 데이터는 제외!
SELECT [컬럼명] FROM [테이블1명] AS A LEFT JOIN [테이블2명] AS B ON A.[컬럼1명] = B.[컬럼1명] AND ... AND A.[컬럼n명] = B.[컬럼n명] WHERE B.[컬럼명] IS NULL -- A - B 의미 ;
실습
1. 내 포켓몬과 친구의 포켓몬에 어떤 타입들이 있는지 중복 제외하고,
같은 타입은 한 번씩만 가져와 주세요.
2. 내 포켓몬과 친구의 포켓몬 중에 grass 타입들의 포켓몬 번호와 이름을
중복 포함하여 전부 가져와 주세요.
my, friend's를 whose라는 별명을 사용하여 구분해주세요.
![](https://blog.kakaocdn.net/dn/dLL04W/btrUzkD10Mf/6szk5YLk5fNPyhnmNqJrr0/img.png)
/*
1. 내 포켓몬과 친구의 포켓몬에 어떤 타입들이 있는지 중복 제외하고,
같은 타입은 한 번씩만 가져와 주세요.
*/
SELECT m.type
FROM mypokemon AS m
UNION
SELECT p.type
FROM friedpokemon AS p
;
SELECT distinct m.type
FROM mypokemon AS m
UNION
SELECT distinct p.type
FROM friedpokemon AS p
;
/*
2. 내 포켓몬과 친구의 포켓몬 중에 grass 타입들의 포켓몬 번호와 이름을
중복 포함하여 전부 가져와 주세요.
my, friend's를 whose라는 별명을 사용하여 구분해주세요.
*/
SELECT m.number,
m.name,
'my' AS whose
FROM mypokemon AS m
WHERE m.type = 'grass'
UNION ALL
SELECT p.number,
p.name,
"friend's" AS whose
FROM friendpokemon AS p
WHERE p.type = 'grass'
서브쿼리(조건에 조건 더하기)
- 하나의 쿼리 내 포함된 또 하나의 쿼리
- 반드시 괄호 안에 존재해야함
SELECT
,FROM
,WHERE
,HAVING
,ORDER BY
절에 사용 가능INSERT
,UPDATE
,DELETE
문에도 사용 가능- 서브 쿼리에는
;
을 붙이지 않아도 됨
서브쿼리 장단점
장점
- 쿼리 작성에 있어 편리함
단점
- 연산 비용 추가
- 최적화 불가
- 쿼리 복잡
SELECT절 서브쿼리(스칼라 서브쿼리)
- 서브쿼리의 결과값이 반드시 하나의 값
- 주로 조건식에
PK
를 활용
- 주로 조건식에
SELECT [컬럼명]
(SELECT [컬럼명]
FROM [테이블명]
WHERE [조건식])
FROM [테이블명]
WHERE 조건식
;
FROM절 서브쿼리(인라인 뷰 서브쿼리)
- 서브쿼리 결과는 반드시 하나의 테이블
- 서브 쿼리로 만든 테이블은 반드시 별명을 가져야함
SELECT [컬럼명]
FROM (SELECT [컬럼명]
FROM [테이블명]
WHERE 조건식) AS [테이블 별 명]
WHERE 조건식
;
WHERE절 서브쿼리(중첩 서브쿼리)
WHERE
절의 서브쿼리는 반드시 결과값이 하나의 컬럼(EXISTS
제외)- 하나의 컬럼에는 여러 개의 값이 존재할 수 있음
- 연산자와 함께 사용
- 일반적으로
WHERE [컬럼명] [연산자] [서브쿼리]
형식 사용
- 일반적으로
SELECT [컬럼명]
FROM [테이블명]
WHERE [컬럼명] [연산자] (SELECT [컬럼명]
FROM [테이블명]
WHERE 조건식);
서브쿼리에 사용하는 연산자
대부분의 WHERE
절의 서브쿼리는 비교연산자를 사용
비교 연산자
![](https://blog.kakaocdn.net/dn/bo1mQU/btrUxdSTzW6/AX4XuQQG4U9DvvQjiM11D0/img.png)
비교 연산자만 사용 시, WHERE
절의 서브 쿼리는 반드시 결과값이 하나의 값이어야 합니다.
주요 연산자
![](https://blog.kakaocdn.net/dn/2apfL/btrUIfgSBoN/HOJgIwVF1O9zNA6MkfuYEK/img.png)
주요 연산자 사용 시, WHERE
절의 서브 쿼리는 반드시 결과값이 하나의 컬럼이어야 합니다.
EXISTS
는 단독으로 사용하며, 결과값이 여러 컬럼이어도 됩니다.ALL
연산자 팁<
: 서브쿼리 결과의최솟값
보다작은 지
확인>
: 서브쿼리 결과의최댓값
보다큰 지
확인
ANY
연산자 팁<
: 서브쿼리 결과의최댓값
보다작은 지
확인>
: 서브쿼리 결과의최솟값
보다큰 지
확인
EXISTS
연산자 팁- 값이 있는지 확인할 때 사용하는 연산자로
TRUE/FALSE
반환
- 값이 있는지 확인할 때 사용하는 연산자로
실습
포켓몬고 DBA
팀에 이슈가 생겼습니다..!!
레거시 쿼리에서 문제가 생겨서 리팩토링 하기로 했습니다.
문제가 생긴 요구사항을 볼까요?
1. 내 포켓몬 중에 몸무게가 가장 많이 나가는 포켓몬의 번호를 조회
2. 속도가 모든 전기 포켓몬의 공격력보다 하나라도 작은 포켓몬의 번호를 조회
3. 공격력이 방어력보다 큰 포켓몬이 있다면 모든 포켓몬의 이름 조회
음… 서브 쿼리를 이용해서 SQL
을 작성해 봅시다.!
![](https://blog.kakaocdn.net/dn/cpqddd/btrUzlXg2qP/6pWQoteYg57tGvpNzZvmgk/img.png)
/*
1. 내 포켓몬 중에 몸무게가 가장 많이 나가는 포켓몬의 번호를 조회
*/
SELECT number
FROM ability
WHERE weight = (SELECT MAX(weigth) FROM ability)
;
/*
2. 속도가 모든 전기 포켓몬의 공격력보다 하나라도 작은 포켓몬의 번호를 조회
*/
SELECT number
FROM ability
WHERE speed < ANY(SELECT attack
FROM ability
WHERE type = 'electric')
;
/*
3. 공격력이 방어력보다 큰 포켓몬이 있다면 모든 포켓몬의 이름 조회
*/
SELECT name
FROM mypokemon
WHERE EXISTS (SELECT name
FROM ability
WHERE attack > defense)
;
수정, 삭제
데이터 삭제하기
DELETE FROM [테이블명]
WHERE 조건식
;
DELETE FROM mypokemon
WHERE attack > 50
;
데이터 수정
UPDATE [테이블명]
SET [컬럼명] = [수정값]
WHERE 조건식
;
UPDATE mypokemon
SET name = 'shinkai'
WHERE name = 'chikorita'
;
제약 조건
- 데이터를 입력할 때 실행되는 데이터 입력 규칙
- 테이블을 만들거나 변경하면서 설정
CREATE TABLE
및ALTER TABLE
구문
![](https://blog.kakaocdn.net/dn/Hj4Cv/btrUBaHUWwr/xHWZV57LTvNBSC1I9HlkFk/img.png)
CREATE TABLE [테이블명] (
[컬럼명] [데이터 타입] [제약 조건],
[컬럼명] [데이터 타입] [제약 조건],
...
);
CREATE TABLE member(
id Long PRIMARY KEY, -- 기본키
phone VARCHAR(11) UNIQUE, -- 연락처는 서로 다른값을 가져야함
name VARCHAR(20) NOT NULL, -- 이름은 NULL이면 안됨
gender INT DEFAULT 0 -- 남: 0, 여: 1
FOREIGN KEY(team_id) REFERENCES team(id) -- 팀 id를 외래키로 사용
-- team_id는 team 테이블의 기본키(PK)
);
권한과 DCL(Data Control Language)
SQL
은 다음 4가지로 분류가 가능합니다.
![](https://blog.kakaocdn.net/dn/c631Uc/btrUHMMJYSs/kL41oCcd6YgpWgEfJKkmF1/img.png)
데이터 베이스는 권한에 따라서 데이터 접근을 제어 할 수 있습니다.
![](https://blog.kakaocdn.net/dn/4N6Ri/btrUxqdqcMM/hnljXVi3H5VM4qZKhv9oPK/img.png)
사용자 확인하기
-- MySQL 기본 데이터베이스인 mysql 데이터베이스 선택
USE mysql;
-- 사용자 목록 조회
SELECT user, host FROM user;
사용자 생성, 삭제
- ip주소가
%
이면 모든 ip에서 접근을 허용한다는 의미
```sql -
- 사용자 생성
CREATE USER [사용자명]@[ip주소];
- 사용자 생성
-- 비밀번호와 함께 사용자 생성
CREATE USER [사용자명]@[ip주소]
IDENTIFIED BY '[사용자 비밀번호]'
;
-- 사용자 삭제
DROP USER [사용자명]@[ip주소];
### 권한 확인, 삭제, 적용
```sql
-- 권한 부여
GRANT [권한]
ON [데이터베이스명].[테이블명]
TO [사용자명]@[ip주소];
-- 권한 확인
SHOW GRANTS FOR [사용자명]@[ip주소];
-- 권한 삭제
REVOKE [권한]
ON [데이터베이스이름].[테이블이름]
FROM [사용자명]@[ip주소];
-- 권한 적용
FLUSH PRIVILEGES;
권한 종류
권한 종류는 크게 3가지 입니다.
- SUPER(글로벌 권한)
GRANT SUPER ON *.* TO seaung@localhost;
- 모든 데이터베이스의 모든 테이블에 권한이 있음
- EVENT(DB 권한)
GRANT EVNET ON members.* TO seaung@localhost;
members
데이터 베이스의 모든 테이블에 권한이 있음
- 특정 키워드(오브젝트 권한)
GRANT SELECT, INSERT, UPDATE ON *.* TO seaung@localhost;
- 모든 데이터베이스의 모든 테이블에
SELECT
,INSERT
,UPDATE
기능만 권한 있음
트랜잭션과 TCL(Transaction Control Language)
- 데이터베이스의 데이터 상태를 바꾸는 작업(
transaction
)
트랜잭션 과정
![](https://blog.kakaocdn.net/dn/bK9xTt/btrUxedhXlN/h2U6KTUi4RkhBFKcATSko1/img.png)
-- 트랜잭션 시작하기
START TRANSCATION;
-- 트랙잭션 확정
COMMIT;
-- 트랜잭션 이전으로 돌아가기
ROLLBACK;
-- 세이브포인트 만들기
SAVEPOINT [세이브포인트명];
-- 세이브포인트로 돌아가기
ROLLBACK TO [세이브포인트명];
'데이터베이스 > 0 + SQL' 카테고리의 다른 글
[패스트캠퍼스] 2. SQL 기초1 (0) | 2022.12.19 |
---|---|
[패스트캠퍼스] SQL 강의 1. 데이터베이스의 개요와 SQL 문법 (2) | 2022.12.05 |