낼름낼름 동동이

[ASAC 11일차] group by, having, join 본문

데이터분석/SQL

[ASAC 11일차] group by, having, join

인죠인간 2024. 4. 5. 08:41

 

4월 4일의 기록

벌써 4월 4일이다. 봄날씨가 되면서 서울에도 벚꽃이 만개하고 있어서 기분이 좋다.

ASAC 과정을 시작한지도 3주차가 지나고 있는데, 매일의 수업을 따라가면서 꾸준히 복습을 하지만 그럼에도 시간이 너무 빨리 가서 부족함을 더 빨리 느끼는 것 같다.

당연한건가 싶다가도 벌써부터 이러는데 ‘머신러닝, 딥러닝 분야까지 가면 잘 해낼 수 있을까’ 하는 걱정이 살포시 생긴다.

우선은 지금 하고 있는 것들에 집중하면서 열심히 해보자.

오전에는 파이썬 평가를 진행했다. 매니저님이 쉬울 거라고 하셔서 믿고 시작했는데, 2번 문제부터 막히면서 시간을 많이 잡아먹었다. 가까스로… 겨우겨우 풀긴 했으니까 다행인가..

역시 코테 준비는 많은 문제를 다양하게 풀어 보면서 익숙해지는게 제일 중요한 것 같다. 많이 풀어본 유형의 문제는 어떻게 풀어야 할지 감을 잡기 좋으니까 말이다.

목차


  1. Group by, having
  2. Join

1. Group by, having


GROUP BY절

  • 그룹으로 묶어주는 역할
  • 집계 함수(Aggregate Function)과 함께 사용
    • 효율적인 데이터 그룹화(Grouping)
    • ex) 사용자 별로 구매한 개수를 합쳐서 출력하고 싶다.
    • select userid, sum(amount) from buybtl group by userid
    • 유저별로 구매한 횟수가 2회 이상일 수 있고, 한번 구매할 때 2개나 5개 등등으로 살 수 있으니까, 이를 합산하기 위해서 유저별로 그룹화를 해줘야 계산할 수 있다.

참고) group by와 함께 자주 사용되는 집계함수

간단 실습(group by)

# buytbl에서 사용자(userid)가 
#구매한 물품의 구매액 (수량 * 가격)을 보려고 한다.

select userID, sum(amount) as 총 구매 수량 from buytbl 
group by userID
order by userID;

#buytbl에서 사용자(userid)가 
#구매한 물품의 구매액 (수량 * 가격)을 보려고 한다.

select userID, sum(amount*price) as 총 구매액 from buytbl 
group by userID
order by userID;

#전체 구매자가 구매한 물품의 개수(amount)평균

select avg(amount) as "평균 구매 개수" from buybtl;

Having 절

  • WHERE 과 비슷한 개념으로 조건 제한 하는 것이지만, 집계 함수에 대해서만 조건을 제한 하는 것이다.
  • HAVING절은 꼭 GROUP BY절 다음에 나와야 한다. 이 순서가 바뀌면 동작하지 않는다.
# 사용자별로 총 구매액 구하기

select userID as "사용자", sum(price*amount) as "총 구매액"
frim buytbl

group by userID;

# 총 구매액이 1000이상인 사용자에게만 사은품 증정하려고 할 때, 
# 어떤 사람인지 추출해보자

select userID as "사용자", sum(price*amount)as "총 구매액"
from buytbl
where sum(price * amount) > 1000
group by userID;

# --> 이렇게 하면 에러가 발생한다. where 는 집계함수에 조건을 걸 수 없다.

select userID as "사용자", sum(price*amount)as "총 구매액"
from buytbl
group by userID
having sum(price * amount) > 1000;

집계함수에 조건을 넣고 싶다면 having을 써야 한다.

+참고) ROLLUP

  • 총합 또는 중간 합계가 필요하다면 사용
  • GROUP BY 절과 함께 WITH ROLLUP 문 사용
#다음 과 같이 사용하면 된다
select num, groupName, SUM(price * amount) as '비용'
from buytbl
group by groupName, num
WITH rollup

 

2. JOIN


조인 (Join)

  • 두 개 이상의 테이블을 서로 묶어서 하나의 결과 집합으로 만들어 내는 것
  • inner join, outer join, cross join, self join

데이터베이스 테이블

  • 중복과 공간 낭비를 피하고 데이터의 무결성을 위해서 여러 개의 테이블로 분리하여 저장한다.
  • 이때, 분리된 테이블은 서로 관게를 가진다.
  • 1댸 다 관계가 대부분이다.

 

종류에 따라 어디까지 참조하게 되는지 잘 알아둬야 한다!

CROSS JOIN

# cross join 의 경우 그냥 n:m 으로 모두 대응을 시킨다.

# 만들 수 있는 모든 조합을 만들어 낸다.
# 언제 사용해??? 
# 주어진 데이터들을 가지고 만들 수 있는 조합을 만들어 낼 때
# 그리고 그 중에서 내가 필요한 조합들을 추려 갈때

# 방법 1) 누가 앞에 오든 상관 없다. 누가 앞에 있냐 차이일 뿐 결과는 동일 
select * from movies cross join members;

# 방법 2) 1개가 아니라 테이블을 그냥 나열 하기

select * from movies, members;

INNER JOIN

# inner join을 앞의 cross join을 기반으로 where으로 추릴 수 있다.
#-> 서브 쿼리

select members.first_name, memebers.last_name, movies.title
from members, movies
where movies.id = members.movie_id;

# 앞에서의 cross join에서의 부분을 조건으로 처리하면
# 양쪽에 둘다 존재하는 값만 살아남으므로
# inner join 의 결과를 만들어 낸다.

# 기준을 members 테이블로 한다면

select ME.first_name, ME.last_name, M.title
from memebers ME
inner join movies M on ME.movie_id = M.id;

# 기준을 movies로 하게 된다면

select ME.first_name , ME.last_name, M.title
from movies M
inner join members ME on ME.movie_id = M.id;

# inner join과 결과가 같고, 
# 다만 기준으로 누구를 먼저 했냐의 차이
# 그러나 문제는 보고자 하는 select에서 정해지므로 왼쪽 셀에
# 누가 오는지가 달라짐

LEFT JOIN, RIGHT JOIN

Left join의 예시

# 영화가 왼쪽 기준일 때, 영화를 기준으로 사람 정보 붙이기

select * from movies as m
left join members as ME on ME.movie_id = m.id;

# 영화를 기준으로 사람의 정보를 붙일 때 보고자 하는 정보가
# 제목, 회원 이름일때!

select M.title, me.first_name, Me.last_name from movies M
left join members as ME on ME.movie_id = M.id;

# 그럼 영화를 오른쪽에 두고 회원을 왼쪽 기준에 두고
# 앞에서처럼 회원의 정보가 있으면 가져오고 없으면 말고 이렇게 만드려면

select * from members as ME
right join movies as M on ME.movie_id = M.id;

 

left join과 right join 비교)

누구를 기준으로 데이터를 왼쪽으로 두냐의 차이다.

 

 

'데이터분석 > SQL' 카테고리의 다른 글

[ASAC 12일차] Case when, SQL의 Rank 방식  (0) 2024.04.05
[ASAC 10일차] SQL 기초  (0) 2024.04.03