[데이터 집계하기 2]
- rollup : 전체 집계를 구한 다음에, 각 단계에 따른 소계를 해주는 기능
select
country,
count(id) as count_user
from `thelook_ecommerce.users`
group by rollup(country);
#연습문제 11-1
#회원(users) 테이블에서 연령대 별 성별의 소계 및 합계를 조회
#일의 자리를 버림 (trunc는 내림)
select
trunc(age, -1) || '대' as age_group,
gender,
count(id) as user_count
from `thelook_ecommerce.users`
group by rollup(age_group, gender)
order by age_group, gender
- window 함수란?
- 일단 함수이다. (input -> 처리 -> output)
-현재 행과 관련있는 테이블 행들에 대해 계산을 수행함
-행 그룹의 값을 계산하고 각 행마다 하나의 결과를 반환함
-계산을 수행하는 범위를 window라고 함 (첫번째부터 현재 행까지가 계산의 범위)
사진 설명을 입력하세요.
cf) 다른 집계 함수는 범위를 정하려면 반드시 group by를 해야 함.
함수
OVER (
[ PARTITION BY 컬럼 ]
[ ORDER BY 컬럼 ]
[ WINDOWING 절 ]
)
select
id,
value,
sum(value) over(order by id) as total
from `weniv.value_list`
복사를 떠서 하나 만들어 놓고, id로 정렬을 시키고,
현재 행을 기준으로 해서 그 순간마다의 집계를 진행한다.
- rank : 순위를 매길 때 사용
select
id,
first_name,
last_name,
country,
age,
rank() over(order by age) as rank
from `thelook_ecommerce.users`
where id between 1 and 20
order by age
#국가별로 쪼개서 집계하려면 partition by 사용
select
id,
first_name,
last_name,
country,
age,
rank() over(partition by country order by age) as rank
from `thelook_ecommerce.users`
where id between 1 and 20
order by age
- dense_rank() : 동일 순위가 있을 때, 다음 순위는 건너뛰지 않고 순차로 번호를 부여함.
select
id,
first_name,
last_name,
country,
age,
dense_rank() over(partition by country order by age) as rank
from `thelook_ecommerce.users`
where id between 1 and 20
order by country, age
- row_number() : 일련 번호로, 1부터 하나씩 증가하는 번호를 부여
select
id,
first_name,
last_name,
country,
age,
row_number() over(order by age) as row_number
from `thelook_ecommerce.users`
where id between 1 and 20
- 연습문제
#연습문제 11-2
#상품정보(products) 테이블에서 각 브랜드 내에서 상품 가격별 순위(brand_rank)를 조회하시오.
#-조회 항목 : id, 브랜드(brand), 상품가격(cost), 각 브랜드 내 상품 가격이 높은 순위(brand_rank)
#-정렬 조건 : 브랜드 오름차순, 상품가격(cost) 내림차순
#-RANK 함수를 이용해서
select
id,
brand,
cost,
rank() over(partition by brand order by cost desc) as rank
from `thelook_ecommerce.products`
order by brand, rank
#연습문제 11-3
select
refresh_date,
combined_key,
deaths,
dense_rank() over(order by deaths desc) as deaths_rank
from `dataflix_covid_dataset.world_covid`
where refresh_date = '2020-06-01'
order by deaths desc
- 탐색 함수 (바로 전과 비교가 필요할 때 사용)
- lag : 이전 행 필드를 읽음
- lead : 다음 행 필드를 읽음
select
id,
first_name,
last_name,
country,
lag(id) over(
partition by country
order by id
) as id_prev,
from `thelook_ecommerce.users`
where id between 1 and 20
order by id
#이벤트 페이지에 다시 접속한 시간 구하기
select
id,
user_id,
created_at,
lag(created_at) over(
order by created_at
) as created_at_prev,
datetime_diff(datetime(created_at), datetime(lag(created_at) over(order by created_at)), second) as prev_visit_second
from `thelook_ecommerce.events`
where user_id = 5781
order by created_at
- FIRST_VALUE, LAST_VALUE : FIRST_VALUE는 그룹 내 첫번째 값을 구하고, LAST_VALUE는 마지막 값을 구한다. (전체 그룹에 대한 마지막 값을 구하려면 ROWS 옵션을 주어야 함)
select
id,
email,
created_at,
first_value(id) over( order by id ) as first_id,
last_value(id) over(
order by id
rows between UNBOUNDED PRECEDING and CURRENT ROW
) as last_id,
last_Value(id) over(
order by id
rows between UNBOUNDED PRECEDING and UNBOUNDED FOLLOWING
) as last_id_unbounded
from `thelook_ecommerce.users`
where id between 1 and 10
order by id
- ROW, UNBOUNDED PRECEDING, UNBOUNDED FOLLOWING
- NTH_VALUE
Q. window의 장점은 ?
한 필드에 계산을 할 때, 어떤 기준으로 할지를 필드 안에서 결정을 할 수 있어서 group by보다 편리함.
각각 다른 기준의 값들을 매 행마다 뽑아낼 수 있다.
각각 집계해서 with로 선언했던 것보다 편리하다.
# 각 제품 브랜드별
select
id,
name,
brand,
category,
retail_price,
NTH_VALUE(id, 1) OVER (PARTITION BY brand ORDER BY retail_price desc) as first_expensive_price_product,
NTH_VALUE(id, 2) OVER (PARTITION BY brand ORDER BY cost desc) as first_expensive_cost_product,
NTH_VALUE(id, 3) OVER (PARTITION BY brand ORDER BY id desc) as last_registered_product
from `thelook_ecommerce.products`
where brand IS NOT NULL
- PERCENT_RANK()
- CUME_DIST() - 누적분포 :n보다 값이 작은 행의 갯수
내용을 입력하세요.
- NTILE() : 나눠서 넣기 (어떤 순서로 나눠서 넣을지도 order by로 바로 결정해서 넣을 수 있다)
-예를 들어, 고객 매출순으로 5등급으로 나누겠다.
select
id,
first_name,
last_name,
country,
age,
ntile(4) over(order by age)
from `thelook_ecommerce.users`
where id between 1 and 20
order by age
- sum은 over()안에 아무것도 안 넣어도 작동이 된다.
- min, max : 경계에 있는 가격대를 알고 싶을 때 사용... 첫 번째 구간의 min이나 두 번째 구간의 max를 구해서...
- 범위 정하기...
ex) 날짜 기준으로 최근 3일만 조회하고 싶다.
1
2
3
4
5
current row, following
preceding, current row
- 데이터 수정 (insert, delete, update)
- insert into : 테이블에 새 레코드를 삽입할 때 사용한다.
-필드명을 넣지 않으면, 필드 순서대로 모든 데이터를 맞춰줘야 한다.
INSERT INTO weniv_product VALUES (12, 'ballpen', 500);
- update : 조건에 맞는 기존 레코드를 수정할 수 있다.
where 조건문 안 넣으면 모든 필드가 수정된다 ㅠㅠ 주의하자 !!!
-> 실수를 방지하기 위해서 장치를 많이 둔다...
(복구할 수 있는 장치 또는 빠르게 인지할 수 있는 장치를 만들어 놓음)
개발DB, 운영DB로 나뉘어져 있는데,
보통 운영DB가 중요함 !! (쿼리창 컬러 세팅 다르게 하기)
UPDATE weniv_product
SET cost = 210000
WHERE id = 1;
여러 레코드를 업데이트할 수 있다.
UPDATE weniv_product
SET cost = cost + 500
WHERE cost < 1000;
- delete : 기존 레코드를 삭제합니다.
실무에서는 권한이 안 주어지는 경우가 많고, 웬만하면 정말 신중하게 사용
추천방법 : select *로 나온 거에 선택을 해서, 마우스 오른쪽 눌러서 delete Row를 클릭해서 쓰기
(실수를 방지하기 위해서)
DBMS에서 where문 없는 delete는 거부하는 경우가 있음 (where에 1-1를 넣어서 처리 가능...)
delete from weniv_product
where id = 11
여러 레코드 삭제
delete from weniv_product
where id > 5
- 테이블 생성 및 수정
- create_database : 데이터베이스를 생성할 때 사용 (생성 권한이 있어야 가능)
캐릭터셋을 잘 지정해서 만드는 게 중요 (utf-8을 기본으로 하는 것을 추천하나, utf8mb4를 추천 (이모지까지 있음))
- create_table
긴 텍스트는 text형으로 지정하는 게 좋음.
- alter table : 컬럼 관련
- alter table 테이블명 add ___ : 컬럼명 추가하기
- alter table 테이블명 rename column ___ to ___ : 컬럼명 수정하기
- drop database
- drop table
- 실무 데이터 분석 예시
extract(dayofweek from created_at)
format_date('%a', created_at) 으로 하면 요일명으로 나옴
'AI School 8기 (LIKELION, 22.12~23.05)' 카테고리의 다른 글
[AI School-TIL] SQL(BigQuery) 7일차_23.02.10 (0) | 2024.12.12 |
---|---|
[AI School-TIL] SQL(BigQuery) 5일차_23.01.27 (1) | 2024.12.12 |
[AI School-TIL] SQL(BigQuery) 4일차_23.01.26 (0) | 2024.12.12 |
[AI School-TIL] SQL(BigQuery) 3일차_23.01.25 (2) | 2024.12.11 |
[AI School-TIL] SQL(BigQuery) 2일차_23.01.20 (0) | 2024.12.11 |