Day 2 복습

  • 숫자형 함수 중 양수, 0, 음수에 따라 1,0, -1을 반환해주는 함수는?
  • 컬럼1과 컬럼2를 다른 형식으로 반환하고 싶다면 쓰는 문자형함수는?
  • 파이썬에서 슬라이싱과 같은 문자형 함수 3가지는?
  • 공백 혹은 일정 텍스트 제거 함수는?
  • 연월일 반환, 시분초 반환 날짜형 함수는?
  • NOW()와 SYSDATE() 차이는?

1. 오늘 배운 내용

데이터 그룹화(GROUP BY, DISTINCT), 집계함수, 총계출산 WITH ROLLUP, GROUPING( ) 함수, HAVING 절과 JOIN을 배웠다. 테이블 간의 연결이 안 되어 해보고 싶던 걸 못해서 이번 JOIN을 배우며 매우 반가웠다.

2. 이해하기 어려웠던 부분

A) JOIN

I'm deadly serious. 믿는 사람 소개로 연결..연결 이게 best인 거 같아요...

-- 형태
select * 
	from  테이블1 as 별칭1 
		join 테이블2 as 별칭2  
			on a.컬럼명1 = b.컬럼명2 

a) 내부조인

  • 다른 테이블과 연결하여 사용할 때 JOIN이 필요하다
  • 한 테이블 내에서 연결하여 출력할 때 서브쿼리가 필요하다
select a.Population, a.Name, b.Name, b.Continent
from city a
join country b
on a.CountryCode = b.code
where b.Continent = 'europe'
order by a.Population
limit 1;
#455	Città del Vaticano	Holy See (Vatican City State)

a) 외부조인

  • left나 right를 쓰면 되는데 더 많은 값을 가진 쪽 방향으로 하면 된다.(부모 테이블로 향한다)
-- 형태
select * 
	from  테이블1 as 별칭1 
		left join 테이블2 as 별칭2  #left or right
			on a.컬럼명1 = b.컬럼명2 

3. 기억해야할 부분

1) 구별하여,

A) GROUP BY

  • OO별 종합할 때 쓰기 좋은 문법이다.
  • WHERE과 ORDER BY 사이에서 쓴다.
#박스오피스에서 2019년 개봉영화중 영화 유형별 최대/최소 매출액과 총매출액 
select movie_type, max(sale_amt) as 최대매출액, min(sale_amt) as 최소매출액, sum(sale_amt) as 총매출액
from box_office where  release_date like '2019%'
group by movie_type 
order by sale_amt;

#대륙별 총면적이 넓고 총인구, 국가수가 많은 순으로
select continent, sum(SurfaceArea) as 총면적, sum(Population) as 총인구, count(*) as 국가수
 from country group by continent order by 2 desc , 3 desc;
 
 -- join과 활용
#부서별 평균봉급, 총 봉급, 인원수  
select d.dept_name, avg(c.salary), sum(c.salary), count(a.emp_no)
from employees a 
join dept_emp b on a.emp_no = b.emp_no
join salaries c on a.emp_no = c.emp_no
join departments d on b.dept_no = d.dept_no
group by b.dept_no;

a) DISTINCT(중복제거에도 사용)

  • select 절 안에서 칼럼명 앞에 명시하면 그룹화와 비슷한 결과를 낼 수 있다.
  • 중복 제거도 가능하다
  • 다만, GROUP BY은 정렬까지 해준다.

B) HAVING 절 활용과 순서 지키기

  • GROUP BY로 집계된 쿼리에서 조건에 맞는 값을 반환하고 싶을 때 사용한다.
  • 그래서 GROUP BY 뒤에 와야 한다.
#개봉 월별로 순위가 탑10에 있는 영화 수 구하기 # 그룹내 조건걸기  having 탑텐 영화가 2편이상 
select extract(year_month from release_date) as 개봉년월, count(*) 개봉편수
from box_office where ranks between 1 and 10
group by extract(year_month from release_date)
having count(*) > 1;

-- 서브쿼리에서 활용
select year(release_date),movie_name,sale_amt 
 from box_office where ranks =1 having sale_amt > (select avg(sale_amt) from box_office where ranks =1);

C) 한글 사용 에러

select if(grouping(b.name) = 1,'전체도시수',b.name), count(A.Name) as '도시 개수' #if와 grouping을 활용하여 전체도시개수 별칭 지정하기
from city a
join country b
on a.CountryCode = b.code
group by b.name with rollup
order by 2 desc;

전체도시를 별칭으로 정하니 1267 에러가 난다. 영어로 바꾸면 이상없다.
Error Code: 1267. Illegal mix of collations (utf8mb4_0900_ai_ci,COERCIBLE) and (latin1_swedish_ci,IMPLICIT) for operation 'if' 0.000 sec...

2) 잘 쓸 거 같아,

A) 총계출산 WITH ROLLUP와 GROUPING( ) 함수

  • 00별 집계를 하고 집계한 값의 총합 역시 나타내고 싶을 때 사용
  • GROUP BY 컬럼명 WITH ROLLUP
  • 다만, 값만 도출되고 명칭 없이 NULL 값으로 나온다.
  • 그 NULL 값에 별칭을 정해주기 위해 IF와 GROUPING 함수를 활용한다.
  • GROUPING( ) 함수의 반환값(1:총계, 0:소계)
-- 2019년 개봉작 중 영화유형별 매출액과 총합
select if(grouping(movie_type) = 1, '전체 총합', movie_type) 영화유형, sum(sale_amt)  #if(조건,조건이 맞을시반환값, 조건이 다를시 반환값)
from box_office where release_date like '2019%' and quarter(release_date) = 1 and sale_amt >= 10000000
group by movie_type with rollup #총계출산 
order by 1, 2 desc;

B) JOIN 사용시 외부키 활용

  • 직원과 관련된 건 emp_no와 부서와 관련된 건 dept_no로 연결되어 있다. 외부키로 다른 테이블과 연결하면 다른 테이블의 자료도 함께 사용할 수 있다.
#부서별 평균봉급, 총 봉급, 인원수  
select d.dept_name, avg(c.salary), sum(c.salary), count(a.emp_no)
from employees a 
join dept_emp b on a.emp_no = b.emp_no
join salaries c on a.emp_no = c.emp_no
join departments d on b.dept_no = d.dept_no
group by b.dept_no;

C) 집계함수

  • count(),min( ), max(), avg() , SUM(), VAR_POP(), STDDEV_POP()
  • 개수, 최솟값, 최댓값, 평균, 총합, 분산, 표준편차
  • 단, 집계함수 사용시 자료가 꼬일 수 있다.
# 유럽에서 인구가 가장 작은 국가
select name, min(Population)
from country where  Continent = 'europe';
#Holy See (Vatican City State)	1000 정답
# Albania	1000  오답: 가장 작은 인구는 맞지만 국가명과 매치하진 않는다, 단순위 맨 위 국가가 나왔다. 그래서 서브쿼리를 써야한다.
--  서브쿼리 (한 테이블에서 집계쿼리 활용할 때)
select a.Name, b.min_Population 
from (select min(Population) as min_Population from country where Continent = 'europe')b, 
country a where a.Population = b.min_Population;
#Holy See (Vatican City State): 1000

-- join과 활용할 때도 서브쿼리가 필요하다.
# 세계에서 인구가 가장 작은 도시
select min(a.Population), a.Name, b.Name, b.Continent 
from city a
join country b
on a.CountryCode = b.code
#42	Oranjestad	Aruba	North America (오답: 인구와 이름 미스매치)

# 파생 테이블 서브쿼리
select c.min_Population, a.Name, b.Name, b.Continent #인구와 이름 미스매치
from (select min(Population) as min_Population from city) c, city a
join country b
on a.CountryCode = b.code
where a.Population = c.min_Population;
#정답: 42	Adamstown	Pitcairn	Oceania 
profile
Learning&Running

0개의 댓글