-- 코드를 입력하세요
select a.YEAR
, a.MONTH * 1 as MONTH
, count(a.USER_ID) as PUCHASED_USERS
, round(count(a.USER_ID)/(select count(u.USER_ID) from USER_INFO u where date_format(u.JOINED, '%Y') = '2021'), 1) as PUCHASED_RATIO
from (
SELECT distinct b.USER_ID
, date_format(b.SALES_DATE, '%Y') YEAR
, date_format(b.SALES_DATE, '%m') MONTH
, date_format(b.SALES_DATE, '%Y-%m') YM
from ONLINE_SALE b
inner join USER_INFO u
on b.USER_ID = u.USER_ID
and date_format(u.JOINED, '%Y') = '2021'
) a
group by a.YM
order by YEAR, MONTH
# select a.YEAR
# , a.MONTH * 1 as MONTH
# , count(distinct a.USER_ID) as PUCHASED_USERS
# , round(count(distinct a.USER_ID)/count(distinct b.USER_ID), 1) as PUCHASED_RATIO
# from (
# SELECT distinct b.USER_ID
# , date_format(b.SALES_DATE, '%Y') YEAR
# , date_format(b.SALES_DATE, '%m') MONTH
# , date_format(b.SALES_DATE, '%Y-%m') YM
# from ONLINE_SALE b
# ) a
# inner join USER_INFO b
# on date_format(b.JOINED, '%Y-%m') <= a.YM
# and b.GENDER is not null
# group by a.YM
# order by YEAR, MONTH
문제 제대로 안읽음;;
이게 레벨 5던데, 문제 자체가 그냥 헷갈림...내가 대충 읽은건가;;
첨에 아래 쿼리 만들었는데,,
아래 쿼리는 (매월 구매회원 / 매월 회원수)을 구하는거임...아 이정도 되니까 레벨5 구나 싶었음.
근데 아무리 돌려도 정답이 아니라길래;;
뭐 2021년 회원 중...이라는;; 이걸 읽지도 않고, 반올림 하는것도 안읽고;;
위 쿼리에선 스칼라서브쿼리를 사용하였다, 2021년 이라는 데이터에 대해서 반복적으로 가져올테니, 매 행마다 실행하는게 아니라,
한번 실행하고 메모리에 올려두고 재사용할테니 요게 더 빠를 거라 판단,
아래 쿼리의 경우 매년 매월 이라는 그나마 좀 다양한 경우의 수가 있기에, 범위가 커질수록 스칼라서브쿼리가 불리할거라 판단했고,
조인을 통해 가져오는 영역은 count(distinct b.USER_ID) 뿐일거라, 범위의 데이터를 통으로 가져오는게 아니라, 저걸 위한 데이터를 알아서 옵티마이저가 잘 연산해 주겠지 하는 막연한 믿음으로 작성한 쿼리,
-- 코드를 입력하세요
SELECT date_format(b.SALES_DATE, '%Y') as YEAR
# , cast(date_format(b.SALES_DATE, '%m') as unsigned) as MONTH
, date_format(b.SALES_DATE, '%m')*1 as MONTH
, a.GENDER
, count(distinct a.USER_ID)as USERS
from USER_INFO a
inner join ONLINE_SALE b
on a.USER_ID = b.USER_ID
where a.GENDER is not null
group by date_format(b.SALES_DATE, '%Y%m'), a.GENDER
order by YEAR, MONTH, GENDER, USERS
select r.CATEGORY
, r.PRICE as MAX_PRICE
, r.PRODUCT_NAME
from (
select @rank := if(@cate = t.CATEGORY, @rank + 1, 1) as num
, @cate := t.CATEGORY
, t.CATEGORY
, t.PRICE
, t.PRODUCT_NAME
from (
SELECT a.PRODUCT_ID
, a.PRODUCT_NAME
, a.PRODUCT_CD
, a.CATEGORY
, a.PRICE
from FOOD_PRODUCT a
where a.CATEGORY in ('과자', '국', '김치', '식용유')
order by a.CATEGORY, a.PRICE desc
) t
) r
where r.num = 1
order by r.PRICE desc
select t.CATEGORY
, t.PRICE as MAX_PRICE
, t.PRODUCT_NAME
from (
SELECT a.PRODUCT_ID
, a.PRODUCT_NAME
, a.PRODUCT_CD
, a.CATEGORY
, a.PRICE
, rank() over(partition by a.CATEGORY order by max(a.PRICE) desc) as r
from FOOD_PRODUCT a
where a.CATEGORY in ('과자', '국', '김치', '식용유')
group by a.PRODUCT_ID
) t
where t.r = 1
order by t.PRICE desc
두가지 버전,
MYSQL 8부터 오라클 처럼 partition by를 지원하는 윈도우 함수가 가능하다. 핵 편함.
하지만, 5.7까지는 안되니깐, 여기선 변수를 사용한 처리가 가능하다.(자료구조상 사이즈 1개 짜리 큐를 이용하는 느낌?)
SELECT left(SALES_DATE, 10) as SALES_DATE
, PRODUCT_ID
, USER_ID
, SALES_AMOUNT
from ONLINE_SALE A
where left(SALES_DATE, 7) = '2022-03'
UNION ALL
SELECT left(SALES_DATE, 10) as SALES_DATE
, PRODUCT_ID
, null
, SALES_AMOUNT
from OFFLINE_SALE A
where left(SALES_DATE, 7) = '2022-03'
order by SALES_DATE, PRODUCT_ID, USER_ID
SELECT date_format(SALES_DATE, '%Y-%m-%d') as SALES_DATE
, PRODUCT_ID
, USER_ID
, SALES_AMOUNT
from ONLINE_SALE A
where SALES_DATE between date('2022-03-01') and date('2022-03-31')
UNION ALL
SELECT date_format(SALES_DATE, '%Y-%m-%d') as SALES_DATE
, PRODUCT_ID
, null
, SALES_AMOUNT
from OFFLINE_SALE A
where SALES_DATE between date('2022-03-01') and date('2022-03-31')
order by SALES_DATE, PRODUCT_ID, USER_ID
-- 계정 생성
> create user ${User}@${Host} identified by ${Password}
-- User = login id
-- Host = remote ip | '%' (all)
-- Password = 486 (윤하...)
(하루에 네번 사랑을 말하고...여덟번 웃고...여섯번의...)
-- 모든 권한 부여
> grant all privileges on ${DB}.${Table} TO ${User}@${Host}
-- option identified by ${Password};
-- option 적용시 비밀번호 바뀜
-- DB = 적용할 Database ( possible * )
-- Table = 적용할 Table ( possible * )
-- 권한 적용
> flush privileges
-- 권한 확인
> show grants for ${User}@${Host}