SQL 문법 정리

2023. 2. 23. 20:39SQL 강의 정리/4주차

2023-02-23 (목) 15:08

배웠던 SELECT 문 문법을 정리하는 시간을 가져보겠습니다

 

첫 번째! -SHOW, SELECT, FROM-

DB에 저장된 테이블을 살펴봅시다 

스파르타DB에는 TABLE을 TABLES라는 곳에 보관합니다 

어떤 테이블이 있는지 보기 위해서는 

SHOW를 사용합니다

SHOW TABLES

컨트롤+엔터로 출력해 보겠습니다

DB에 보관된 TABLE들

정보를 꺼내와 볼까요?

SELECT (필드명) FROM (테이블명) 형태로 정보를 꺼내올 수 있습니다

users 테이블을 출력해 보겠습니다

SELECT * FROM users 

users 테이블

필드명 자리에 *은 전체를 의미합니다 즉 users 테이블에 저장된 필드와 그 값 모두를 선택하여 출력한다는 것을 의미합니다

그러면 users 테이블에서 user_id, name, email 필드만 출력해 보겠습니다

SELECT user_id, name, email FROM users 

SELECT절을 통해 선택한 필드만 출력되었습니다 

 

정리하겠습니다

-SELECT는 DB에 저장된 정보를 불러올 때 사용합니다

-기본적인 형태는 SELECT (필드명) FROM(테이블 명) 입니다

-여러 필드를 출력하기 위해서는 반드시 ,(쉼표)로 구분해주어야 합니다

 

두 번째! -WHERE

WHERE절은 조건문이라고 부르기도 합니다 

WHERE절에서 정한 조건을 부합하는 것만 출력시킵니다 

 

-특정 값만 가져올 때

이번에는 orders 테이블을 보겠습니다

SELECT * FROM orders

orders 테이블

course_title 필드에서 값이 웹개발 종합반인 것만 출력해 보겠습니다 

SELECT * FROM orders

WHERE course_title = '웹개발 종합반'

잘 출력되었습니다!

특정 값을 가진 것 만을 출력하기 위해서는 

SELECT (필드명) FROM(테이블명)

WHERE (값을 가진 필드명) = ('특정 값')

형태로 사용합니다 

+)문자일 때에는 ''를 붙여주어야하고 숫자일 경우 생략이 가능합니다 

+)특정값을 제외하고 싶을 때에는

SELECT (필드명) FROM(테이블명)

WHERE (값을 가진 필드명) != ('특정 값')

을 사용합니다

 

-특정범위 출력을 원할 때

orders 테이블을 봅시다

created_at 필드는 주문 날짜를 의미합니다 

주문 날짜가 2020-07-13에서 2020-07-15까지인 주문 정보를 출력해 봅시다

SELECT * FROM orders

WHERE created_at BETWEEN '2020-07-13' AND '2020-07-16'

출력해보겠습니다

13일부터 15일까지의 주문정보가 출력되었습니다!

BETWEEN은 시작범위와 끝범위 사이의 모든 값을 출력해줍니다

SELECT (필드명) FROM(테이블명)

WHERE (해당필드명) BETWEEN (범위시작점) AND (범위끝)

형태로 사용합니다

+)왜 15일까지 주문을 보는데 범위를 16일로 지정했나

 15일로 끝 범위를 설정한다면 2020-07-15 00:00:00까지만 출력됩니다 

+)숫자인데 왜 ''으로 묶어주었나?

 날짜에 기호가 포함되었기 때문입니다

 

-범위가 아닌 특정 값을 포함하는 것만 출력하고 싶을 때

먼저 checkins 테이블을 보겠습니다

SELECT * FROM checkins

checkins 테이블

week 필드는 주차를 의미합니다 

1주차와 3주차에 해당하는 결과만 보고싶을 때에는 

IN을 사용합니다

SELECT * FROM checkins

WHERE week IN (1,3)

week가 2주차에 해당하는 것들은 제외시키고 1,3 주차만 출력되었습니다 

SELECT (필드명) FROM (테이블명)

WHERE (해당필드명) IN(값,값) 형태로 사용합니다

+) 값이 정확해야합니다 

 created_at필드에서 '2020-08-10', '2020-08-12' 를 출력하고자 할 때 저렇게만 쓰면 출력되는 것이 없습니다 

 왜냐하면 creater_at 필드에는 2020-08-10 값이 없기 때문입니다 정확한 값을 지정하여 넣어주어야 합니다

 

-특정 문자나 숫자를 포함하는 값만 출력할 때

users 테이블을 보겠습니다

SELECT * FROM users

email 필드에서 naver를 사용하는 회원을 출력하고자 할 때에는 

SELECT * FROM users 

WHERE email LIKE '%naver%'

naver.com을 사용하는 유저의 정보가 출력되었습니다 

LIKE는 특정 문자를 포함하는 값을 출력합니다 

SELECT (필드명) FROM (테이블명)

WHERE (해당 필드명) LIKE ('_OR%값_OR%')

형태로 LIKE를 사용할 수 있습니다

+)문자열을 지정할 때에는 %과 _을 사용할 수 있습니다 

 %은 값 앞이나 뒤에 몇 글자가 있든 값이 포함되어 있으면 출력합니다 

 _(언더바)는 좀 더 확실한 결과를 얻고자 할 때 사용합니다 

 _A_ 는 A를 2번째 자리에 가진 3글자를 의미합니다 

 __A 는 A를 3번째 자리에 가진 3글자를 의미합니다 

자세한 것은 

https://www.w3schools.com/sql/sql_like.asp 참고!

 

세 번째! -LIMIT, DISTINCT, COUNT

LIMIT는 출력 값을 제한할 때 사용합니다 

users 테이블은 498번까지 있습니다 

만일 테이블을 파악하기 위해 SELECT문을 사용하려할 때 테이블이 가진 값이 너무 많다면 정보를 출력하는데 시간이 걸립니다!

그렇기에 LIMIT를 사용하여 해당 테이블에서 가져올 정보의 수를 제한할 수 있습니다

SELECT * FROM users

WHERE email like '%naver%'

LIMIT 10

 LIMIT전 164번 까지 출력되는 값이 10번까지 출력됩니다!

 

DISTINCT는 중복을 제거할 때 사용합니다 

users 테이블에서 유저의 성이 몇가지인지 알아보겠습니다

SELECT DISTINCT(name) FROM users

 

 

 

 

 

 

 

 

 

users 테이블에 저장된 유저들의 성씨는 54가지라는 것을 알수있습니다 

DISTINCT는 해당 필드의 중복된 값을 지우고 출력해줍니다 

 

 

 

 

 

 

 

 

 

 

 

 

users 테이블의 총 회원의 수는 얼마일까요?

SELECT COUNT(*) FROM users

498명입니다 확인해볼까요?

SELECT DISTINCT(name) FROM users를 사용하여 users 테이블을 불러온 후 마지막 번호를 보겠습니다

498번이 마지막입니다!

 

다섯 번째! -GROUP BY, ORDER BY,Alias

GROUP BY는 선택한 필드를 기준으로 그룹시켜줍니다

만약 users 테이블의 name필드에서 회원의 성 씨별로 몇 명이 있는지 알기 위해서 GROUP BY를 사용하지 않는다면 

SELECT count(*) FROM users

WHERE name = '%김%'

을 성 씨 가짓수인 54번 반복해야 합니다 

이럴 때 GROUP BY를 이용한다면 더 쉽고 빠르게 원하는 결과값을 출력할 수 있습니다

SELECT name ,count(*) FROM users

GROUP BY name

name 필드와 성 씨별 count가 집계되어 출력되었습니다 

그렇다면! 

GROUP BY된 테이블의 형태는 어떨까요

SELECT * FROM users

GROUP BY name 

성 씨별로 하나를 차지하고 총 54개의 값을 출력했습니다 

GROUP BY와 COUNT의 관계에 대하여 감이 잡히나요?

조금만 더 봅시다 

SELECT * FROM users

WHERE name = '이**'

GROUP BY name의 1행에는 

SELECT * FROM users

WHERE name = '이**' 의 정보가 담긴 것과 마찬가지입니다

 

그렇기에

SELECT name,COUNT(*) FROM users

WHERE name 한다면

이런 모습을 볼 수 있습니다 

이제 왜 GROUP BY를 이용해야하는지 GROUP BY에서 COUNT(*)을 하면 저렇게 출력되는지 이해할 수 있을 겁니다!

 

이렇게 출력된 결과를 정렬하기 위해서는 

ORDER BY를 사용하면 됩니다 

SELECT name ,count(*) as cnt FROM users

GROUP BY name

ORDER BY cnt desc

ORDER BY에서 DESC는 내림차순(높은거->낮은거), ASC는 오름차순(낮은거->높은거)입니다

ORDER BY (필드명) ASC or DESC를 사용해주면 됩니다

 

SELECT name ,count(*) as cnt FROM users 에서 

COUNT(*)뒤에 as cnt는 Alias라고 부릅니다 

별칭을 붙여주어 해당 쿼리에서 대신 사용 가능합니다 

 

여섯 번째! -INNER JOIN, LEFT JOIN

JOIN은 테이블과 테이블을 합칠 때 사용합니다 

INNER JOIN은 공통된 필드를 대상으로 테이블 전체를 합칩니다 

users 테이블과 orders 테이블을 user_id 필드를 대상으로 INNER JOIN 시켜보겠습니다

users 테이블
orders 테이블

SELECT * FROM users u

INNER JOIN orders o

on u.user_id = o.user_id

만일 회원의 이름과 회원이 신청한 강좌명, 결제방법을 알기위해서는 한 테이블에서 해결하기 어렵습니다 이럴 때 JOIN을 통해서 두 테이블을 하나로 합치고 원하는 데이터만 뽑아 출력시킬 수 있습니다

SELECT u.name, o.course_title, o.payment_method FROM users u

INNER JOIN orders o

on u.user_id = o.user_id

+)테이블에 Alias를 부여할 때에는 테이블명 (별칭) 형태로 부여할 수 있습니다 

+)JOIN 상태일 때에는 별칭을 통해 어느 테이블의 필드인지를 구분시켜야 합니다(오류예방)

 Alias를 사용하지 않는다면 users.name 이렇게 사용해야겠죠?

 

LEFT JOIN은 선택된 하나의 테이블을 기준으로 다른 테이블을 JOIN시키는 것입니다 

users 테이블과 point_users 테이블을 통해 알아보겠습니다 

users 테이블
point_users 테이블

마찬가지로 user_id를 기준으로 LEFT JOIN 해보겠습니다 

값이 존재하지 않는 것을 의미하는 NULL 값이 보입니다 

회원가입은 했지만 point가 없는 유저의 경우는 point_users 테이블에 정보가 없습니다 그렇기에 NULL값을 가지게 됩니다

같은 조건으로 INNER JOIN 하면 어떻게 출력될까요?

NULL값이 없습니다 

LEFT JOIN의 경우는 기준이 된 users 테이블의 행과 같은 수의 행을 가집니다 (498개)

INNER JOIN의 경우 범위가 더 작은 point_users와 같은 수의 행을 가집니다(271개)

INNER JOIN과 LEFT JOIN의 차이를 알았다면 사용방법도 알아야 합니다 

그건 이전 포스팅을 통해 알아보는 걸로 하고 넘어가겠습니다 

 

일곱 번째 -SUBQUERY,WITH

서브쿼리는 쿼리문 안의 쿼리입니다 

서브쿼리를 이용하지 않아도 데이터를 찾아보고 보기 좋게 출력하는데 문제는 없지만 

서브쿼리를 사용한다면 더욱 깔끔한 쿼리를 통해 원하는 정보를 얻을 수  있습니다!

이 부분부터는 이전 글에 자세히 적었기에 간단하게 문법 형태만 적고 넘어가겠습니다

 

WHERE절에 사용하는 서브쿼리를 먼저 보겠습니다 

select * from 테이블명

where 필드명 in (서브쿼리)

서브쿼리 안에는 조건을 부여하고 서브쿼리의 조건에 만족한 값을 해당 필드에서 찾아 출력시킵니다

 

select * from 테이블명 
where 필드명 > (서브쿼리)

이런 식으로 비교연산자를 통해 조건문을 사용할 수도 있습니다

 

다음으로 SELECT절에 사용하는 서브쿼리를 보겠습니다

select 필드명, 필드명, 필드명, (서브쿼리) from 테이블

SELECT절에 사용되는 서브쿼리는 출력된 결과값에 새로운 필드를 추가시킬 때 주로 사용됩니다 

서브쿼리를 작성할 때 주의해야 할 것은 결과값을 출력하기 위해 참고해야할 필드가 1:1로 매칭되어야 합니다 

 

마지막으로 FROM절에 사용하는 서브쿼리를 보겠습니다 FROM절에서 사용되는 서브쿼리는 출력된 결과물을 하나의 테이블처럼 사용하여 JOIN시킬 때 주로 사용됩니다

SELECT (필드명),(필드명),(필드명) FROM (서브쿼리) a 

INNER JOIN (서브쿼리)b

ON a.(조인에 필요한 필드명) = b.(조인에 필요한 필드명) 형태로 주로 사용됩니다

 

WITH를 사용하는 이유는 쿼리를 더 간편하고 파악하기 쉽게 표현하기 위해 사용됩니다 WITH를 사용한다면 서브쿼리를 해당 쿼리 내에서 간편한 형태로 재사용 가능합니다 형태를 먼저 보겠습니다WITH AS (사용할 이름1)(서브쿼리),(사용할 이름2)(서브쿼리)SELECT (필드명), (필드명), (필드명)FROM 사용할 이름1 a                       ->a는 별칭입니다INNER JOIN 사용할 이름2 b             -> b도 별칭입니다ON a.(조인에 필요한 필드명) = b.(조인에 필요한 필드명)

 

사용할 이름1을 table1이라고 한다면 해당 쿼리 내에서 길게 작성된 서브쿼리를 복사 붙여넣기 할 필요없이 table1로 간단하게 사용할 수 있습니다 

 

여덟 번째 -case, SUBSTRING, SUBSTRING_INDEX

case는 뜻 그대로 조건을 주고 그 조건에 맞는 값을 새로운 필드를 통해 출력합니다 WHERE과 다른 점은 case는 SELECT절에서 사용한다는 점이고SELECT 절에 사용하는 이유는 출력하기 위해서입니다

 

case는 when,then,else, end로 구성되어 있다 볼 수 있습니다

when은 조건을 나타냅니다

else는 when 이외의 것들을 표현하기 위해 사용됩니다

then은 else 조건에 만족할 때 표현할 값을 의미합니다

end는 case문의 끝을 의미합니다 

 

SELECT (필드명),(필드명),(필드명), 

CASE

WHEN (테이블.필드명) (비교연산자) then (출력문구)

WHEN (테이블.필드명) (비교연산자) then (출력문구)

else (출력문구) end

FROM (테이블명)

형태로 사용됩니다 

+)when을 늘려주면 조건을 추가할 수 있습니다 ()와 as를 이용하면 출력되는 필드에 별칭을 부여할 수 있습니다 

+)SELECT절에 사용되기 때문에 CASE 앞이나 뒤에 필드가 있다면 ,를 사용하여 구분해 주어야 합니다

 

SUBSTRING은 특정 부분을 출력할 때 사용합니다

SELECT (필드명), SUBSTRING(필드명,값의 시작점,시작점에서 출력을 원하는 지점) FROM 테이블명

형태로 사용됩니다 

간단한 예시로 created_at(생성날짜) 필드에 2020-09-13 13:30:56 (xxxx-xx-xx oo:oo:oo 날짜형태의 값)가 있을 경우

SUBSTRING(created_at,1,10)을 사용한다면 2020-09-13까지 출력됩니다

SUBSTRING(created_at,12,8)을 사용한다면 13:30:56이 출력됩니다 

+)공백까지 카운트합니다

 

SUBSTRING_INDEX는 하나의 기준점 가지고 기준의 앞 또는 뒤를 출력할 때 사용합니다 

SELECT SUBSTRING_INDEX(해당 필드명,기준점,-1 or 1) -1은 기준점 뒤, 1은 기준점 앞을 출력합니다

간단한 예시로 email 필드에 uauauauau@naver.com가 있을경우

SELECT SUBSTRING_INDEX(email,'@',-1)를 사용하면 naver.com이 출력되고

SELECT SUBSTRING_INDEX(email,'@',1)을 사용하면 uauauauau가 출력됩니다 

+)@나 문자의 경우 꼭 ''을 사용해 주어야 합니다 

 

이것으로 SQL과정에서 배운 문법을 총정리 했습니다 

서브쿼리 쪽부터 조금 넘긴 느낌이지만 그 부분은 문제와 함께 봐야하기 때문에 이전 작성한 글을 통해 이해하는 것이 더 좋을 것 같네요 

혹여 미래의 나를 위해 남겨두는 SQL일지는 이것으로 끝 입니다!

'SQL 강의 정리 > 4주차' 카테고리의 다른 글

subquery (from절, with, when)  (1) 2023.02.22
subquery(1)(where절, select절)  (0) 2023.02.21