Study/CSSU

[CSSU] SQL 정리

MuviSsum 2021. 6. 25. 16:51

 

세 번째 주제 - SQL

세 번째 주제는 Mysql을 기반으로 한 SQL입니다.

사실, 기본적인 구문은 잘 알고 있지만, 이번에 어려운 JOIN 연산까지 싹 살펴보려고 선택했습니다.

(이 글을 쓰기 위해서 프로그래머스의 SQL 모든 문제를 풀고 왔어요 ㅎㅎ)

 

1. SELECT

SELECT는 정말 기본적인 문법이에요.

데이터를 보기 위해서는 SELECT가 있어야 무조건 동작하죠.

밑에 있는 쿼리문을 보면 "*"를 SELECT 했다고 나옵니다.

SELECT *
FROM data;

"*"는 모든 컬럼을 이야기하는 것으로 data라는 테이블에서 모든 데이터가 나오겠죠.

 

하지만 이렇게 기본적으로 쓰진 않죠!

SELECT는 거의 필연적으로 WHERE이라는 구문이 따라옵니다.

data라는 테이블에 밑과 같이 데이터가 있다고 봅시다!

id human name
1 True taewan
2 False wantae

자, 우리는 name이 "taewan"이라는 로우를 뽑을 겁니다.

SELECT *
FROM data
WHERE name="taewan";

"*"로 모든 컬럼을 선택했으니 해당 로우의 모든 데이터가 나오겠죠?

id human name
1 True taewan

여기서 id만 선택하게 되면 어떻게 될까요?

SELECT id
FROM data
WHERE name="taewan";

밑과 같은 결과가 나오게됩니다.

taewan이라는 name을 가진 id는 1이기 때문이죠!!

id
1

 

2. INSERT

처음 봤던 테이블을 가져옵시다.

id human name
1 True taewan
2 False wantae

여기서 새로운 로우를 추가하려면 어떻게 해야 할까요?

자, 이제 INSERT를 써야합니다.

대표적으로 두가지 방법이 있습니다.

INSERT INTO data(id, human, name)
VALUES (3, True, Gutae);

INSERT INTO data
VALUES (3, True, Gutae);
id human name
1 True taewan
2 False wantae
3 True Gutae

첫 번째처럼 컬럼을 명시해서 넣을 때는 필요없는 것은 안 넣을 수도 있어요.

테이블 자체에 nullable이 True 되어있다면 해당 값이 null로 들어가는거죠.

하지만 data라고 테이블만 쓸 때는 모든 것을 다 넣어주어야 하죠.

아! 그리구 id는 default로 autoincrease 되어 있다면 insert시 넣지 않아도 됩니다! ㅎㅎ

 

3. UPDATE

UPDATE는 로우 데이터를 수정할 때 쓰는 명령어이에요.

또 테이블을 가져옵시다!

id human name
1 True taewan
2 False wantae
3 True Gutae

여기서 뭔가 다른 점이 있어요.

name에 3번 혼자 첫 문자가 대문자인거죠!

근데 이름의 첫 문자는 대문자여야되니까 1, 2번을 바꿔 볼게요.

이젠 UPDATE라는 것을 써야합니다.

UPDATE data
SET name = "Taewan"
WHERE id = 1;

UPDATE data
SET name = "Wantae"
WHERE id = 2;

두 쿼리문 모두 실행시키면 밑과 같은 결과가 나오게 됩니다.

id human name
1 True Taewan
2 False Wantae
3 True Gutae

자, 여기 쿼리문을 보면 UPDATE 뒤에는 테이블이 존재하구요,

SET 뒤에는 바꿀 컬럼을 지정합니다.

근데 컬럼을 지정하면 모두 바꿔야 되잖아요?

그래서 WHERE문이 따라옵니다.

WHERE문으로 지정해준 로우만 바뀌도록 만드는 거죠!

 

4. DELETE

이제는 지워 봅시다. 첫 테이블을 또 가져오구요.

id human name
1 True Taewan
2 False Wantae
3 True Gutae

여기서 쿼리문을 실행시킵니다.

DELETE FROM data
WHERE id = 3;

마지막 행을 삭제시키는 쿼리문입니다.

여기서 보면 DELETE는 FROM과 함께 옵니다.

왜 그럴까요? DELETE를 하려는데 어느 테이블에서 삭제를 할지 알아야하기 때문입니다.

하지만 저렇게만 하면 제가 원하는 행이 어떤 것인지 모르겠죠?

그래서 WHERE문으로 id = 3이라는 것을 붙여줍니다.

이렇게 쿼리문으로 C, R, U, D를 모두 보았구요, 이제 좀 더 들어가 볼까요!

 

5. 논리 연산, 비교 연산

WHERE절에서 데이터를 논리, 비교 연산을 할 수 있습니다.

제가 제일 놀랐던 점이 여긴데요,

부등호로 표현할 수 있는 연산이 생각보다 많더라구요.

=, >, <, >=, <=, <>(!=)가 있습니다.

여기서 제일 신기한게 "<>"이 부호입니다.

항상 "!=" 이거만 썼는데 "<>" 얘도 되는지 처음 알았어요. (즉, "다르다"라는 비교연산입니다.)

밑에 쓰는 예시가 있습니다. 5보다 큰 id 값을 가진 데이터 찾기입니다.

SELECT *
FROM data
WHERE 5 > id;

근데 부등호 연산은 숫자만 되는게 아니에요.

여기서 밑과 같이 name으로 "D"보다 큰 것을 찾아라고 하게 되면

SELECT *
FROM data
WHERE "D" < name;

답은 name의 첫 글자가 "D"보다 큰, 즉 "A", "B", "C", "D"로 시작하는 이름빼고 모두 불러오게 됩니다.

이처럼 문자도 비교연산이 가능하니 참고하시길 바래요!

 

그리고 논리연산은 OR와 AND를 지원하는데,

이건 똑같이 밑과 같이 기본적인 논리연산을 따라 쓰시면 됩니다.

SELECT *
FROM data
WHERE id < 3 AND "D" < name;

파이썬이랑 똑같죠? ㅎㅎㅎ

 

6. JOIN

JOIN은 정말 처음 SQL을 접하시는 분들께는 어려워요.

저도 처음엔 조금 사용하기가 어려웠거든요.

하지만 사용하다보니 익숙해지고 right, left를 자유자재로 쓸 수 있게 된 것 같습니다.

프로그래머스 짱짱!!

일단 크게 어떤 종류의 JOIN이 있는지 살펴볼까요?

JOIN은 크게 INNER JOIN, OUTER JOIN으로 나뉘구요,

OUTER JOIN에서도 RIGHT, LEFT, FULL 로 나뉩니다.

INNER JOIN은 둘 사이에 서로 조건이 맞는 결과만 보여주게 됩니다.

SELECT *
FROM TableA A
INNER JOIN TableB B
ON A.key = B.key;

RIGHT OUTER JOIN은 JOIN 뒤에 쓴 테이블의 로우에 우선적으로 맞춘 결과를 보여주게 됩니다.

즉, 밑의 쿼리에서는 테이블 B는 무조건 다 나오게 된다는 말이죠.

SELECT *
FROM TableA A
RIGHT JOIN TableB B
ON A.key = B.key;

LEFT OUTER JOIN은 FROM 뒤에 쓴 테이블의 로우에 우선적으로 맞춘 결과를 보여주게 됩니다.

즉, 밑의 쿼리에서는 테이블 A는 무조건 다 나오게 된다는 말이죠.

SELECT *
FROM TableA A
LEFT JOIN TableB B
ON A.key = B.key;

FULL OUTER JOIN은 두 테이블의 모든 로우에 맞춰 결과를 보여주게 됩니다.

SELECT *
FROM TableA A
FULL OUTER JOIN TableB B
ON A.key = B.key;

여기 나온 쿼리는 밑의 사이트에서 가져온 쿼리입니다.

링크걸어 놓은 사이트에서는 시각적으로 JOIN을 쉽게 설명하기 때문에 한 번 이용하시면 JOIN이 쉬워지실거에요^^

https://sql-joins.leopard.in.ua/

 

SQL Joins Visualizer

Please select how do you want to do SQL JOIN between two table

sql-joins.leopard.in.ua

 

7. UINON

유니온은 찾은 쿼리의 결과를 합치는 효과가 있습니다.

밑과 같이 둘의 결과를 합치면 위의 결과와 밑의 결과가 합쳐져서 결과가 생성됩니다.

SELECT *
FROM data
WHERE id < 3 AND "D" < name

UNION

SELECT *
FROM data
WHERE id >= 3 AND "D" >= name;

 

여기서 잠깐 퀴즈!!

이렇게 하면 data 테이블 전체 조회한 결과와 같을까요? 다를까요??

답은 맨 밑에 놔두겠습니다^^

 

8. ORDER + LIMIT

ORDER은 정말 자주 쓰이는 문법입니다.

뽑은 결과를 정렬해 주는 아주 필수적인 존재!!

오름차순과 내림차순을 ASC, DESC라고 외우기만 한다면 ORDER은 더 이상 생략해도 무방하다고 생각합니다.

딱 저 두가지를 외우고, 원하는 컬럼을 정렬하시면 됩니다 ㅎㅎ

그래도 밑의 예시는 한 번 보고 가야죠!

SELECT *
FROM data
ORDER BY name DESC;

 

자, 이렇게 하면 "name" 컬럼을 기준으로 data의 전체 조회결과가 생기게 됩니다. 

밑의 테이블이 data 테이블이라고 합시다. 데이터를 넣은 순서대로 저장이 되어 있겠죠?

id human name
1 True Taewan
2 False Wantae
3 True Gutae

하지만 이제 밑의 테이블을 보면 name으로 내림차순이 되어 있는 것을 볼 수 있습니다.

Z -> A 쪽으로 정렬이 된 모습이죠.

id human name
2 False Wantae
1 True Taewan
3 True Gutae

이렇듯 본인이 원하는대로 데이터를 정렬하여 뽑아 낼 수 있도록 해주는 것이 ORDER입니다.

 

여기서 하나 더 집고 갈게요.

LIMIT라는 것이 있습니다.

LIMIT는 내가 원하는 만큼만 데이터를 뽑아내는 것인데요.

밑의 쿼리를 실행시키게 되면 LIMIT가 1이니까 제일 위 데이터 하나만 뽑아내게 됩니다.

SELECT *
FROM data
ORDER BY name DESC
LIMIT 1;

그럼 위의 테이블에서 결과는 밑처럼 나오게 됩니다.

id human name
2 False Wantae

LIMIT도 유용하니 참고해두세요!

 

9. GROUP 

그룹은 집계함수와 거의 같이 쓰는 명령어입니다.

GROUP을 지정해서 집계함수로 SUM, COUNT 등을 하는 것이죠.

밑의 예시를 볼까요?

SELECT name, COUNT(*) as count
FROM data
GROUP BY name
HAVING count >= 2;

 

 

name으로 그룹화를 한 모습입니다.

이렇게 되면 같은 이름을 가진 사람이 2명이상 있는 사람들만 결과로 나타나게 되는 것이죠.

HAVING은 GROUP뒤에 나오는 명령어인데, WHERE과 비슷하다고 생각하시면 됩니다.

WHERE이 FROM에 있는 테이블의 전체에서 조건을 걸어준다면,

HAVING은 GROUP안에서 조건을 걸어주는 역할이죠.

프로그래머스 "동명 동물 수 찾기" 문제를 풀어보시면 쉽게 이해 가능하실 겁니다 ㅎㅎ

 

10. 집계함수

마지막으로 집계함수를 알아볼까요?

집계함수는 COUNT, SUM, AVG, MAX, MIN이 있습니다.(더 있을지도...?)

암튼 제일 많이 쓰는 이 5가지의 집계함수를 살펴보겠습니다.

다들 함수가 이름에서 따온거라 쉽게 짐작이 가능할거에요.

 

COUNT는 지정한 컬럼에서  해당 조건의 로우 수를 셉니다.

SUM은 지정한 컬럼에서 해당 조건의 로우 데이터의 합을 출력합니다.

AVG는 지정한 컬럼에서 해당 조건의 로우 데이터의 평균을 출력합니다.

MAX는 지정한 컬럼에서 해당 조건의 로우 데이터의 최댓값을 출력합니다.

MIN는 지정한 컬럼에서 해당 조건의 로우 데이터의 최솟값을 출력합니다.

 

이 함수들은 9번에서 GROUP을 설명할 때, 보여드린 쿼리처럼

GROUP과 함께 많이 사용되어집니다.

거의 따라다니는 함수라고 보면 되고,

이중 셀렉트문을 사용하여 쓰여지기도 합니다 ㅎㅎ

그래도 하나 예시를 보고 가야겠죠?

밑과 같이 쿼리를 치면,

SELECT MAX(id)
FROM data;

밑과 같은 결과가 나오게 됩니다.

MAX(id)
3

저희의 최대 id값은 3이었으니까요 ㅎㅎ

그리고 중요한 점은 컬럼이 MAX(id)처럼 나온다는 것입니다.

as 구문으로 원하는 이름의 컬럼으로 바꾸어 주어도 되고 해당 쿼리를 그냥 조건으로 쓰셔도 무방합니다.

 

11. DISTINCT + NULL

DISTINCT는 중복된 값을 없애주는 친구입니다.

밑과 같이 쿼리를 치게 되면

SELECT DISTINCT name
FROM data;

name이 중복되는 결과는 결과에서 지워서 출력하게 됩니다.

 

NULL은 해당 로우, 컬럼의 데이터에 값이 없는 경우를 뜻합니다.

NULL 연산은 조금 다르게 작동하는데요,

밑처럼 "=" 연산으로 조건을 구분하는 것이 아니라 "is"와 "is not"으로 구분합니다.

SELECT *
FROM data
WHERE name is null;

SELECT *
FROM data
WHERE name is not null;

 

SQL을 정말 기초적인 부분부터 중급적인 부분까지 다루어 봤는데요,

Join 부분과 GROUP + 집계함수가 조금 어려울 것이고 거기까지 익숙해지신다면

DBA나 데이터 엔지니어가 되지 않을 이상, 이정도만 알면 충분할 것 같습니다.

다음엔 어떤 주제를 가지고 올지 생각해봐야겠어요. 그리고 최대한 빠른 시일에 하나 더 쓰자...!!! ㅎㅎ

 

마지막으로 잠깐 퀴즈의 답은 "다르다" 입니다.

id가 2이고 이름이 "D"로 시작하는 로우가 data안에 있다고 칩시다.

이러면 data 전체 조회 결과에 해당 로우가 나오지 않겠죠!

교집합 성질을 잘 생각해보시면 왜 그런지도 찾아내기 쉬울거에요.

반응형

'Study > CSSU' 카테고리의 다른 글

[CSSU] 장고 튜토리얼  (0) 2021.08.22
[CSSU] JWT(JSON Web Token)  (0) 2021.05.07
[CSSU] HTTP request Methods  (0) 2021.04.07