Closed baexxbin closed 2 weeks ago
SELECT
DATE_FORMAT(trans_date, '%Y-%m') AS month,
country,
COUNT(*) AS trans_count,
SUM(IF(state ='approved', 1, 0)) AS approved_count,
SUM(amount) AS trans_total_amount,
SUM(IF(state ='approved', amount, 0)) AS approved_total_amount
FROM Transactions
GROUP BY month, country
GROUP BY
: 날짜(년, 월), 나라로 그룹을 묶어야 함.
DATE_FORMAT(trans_date, '%Y-%m')
사용IF(조건, 참일때 값, 거짓일때 값)
SELECT ROUND(COUNT(DISTINCT A.player_id) / (SELECT COUNT(DISTINCT player_id) FROM activity), 2) AS fraction
FROM activity A
JOIN activity B
on A.player_id = B.player_id
WHERE (A.player_id, A.event_date) in (SELECT player_id, min(event_date) FROM activity group by player_id) AND DATEDIFF(B.event_date, A.event_date) = 1
MIN(날짜)
를 활용해서 각 플레이어의 첫 로그인 날짜만 출력self JOIN
을 활용해서 각 플레이어의 접속 날짜 조합 구하기DATEDIFF(d1, d2)
: d1과 d2의 일수 차이 반환 USER_INFO
테이블ONLINE_SALE
테이블
상품을 구매한 회원수
, 상품을 구매한 회원의 비율
을 년
, 월
별로 출력-- 2021년에 가입한 전체 회원들 중 상품을 구매한 회원수
WITH PURCHASED_DATA AS (
SELECT
YEAR(os.SALES_DATE) YEAR,
MONTH(os.SALES_DATE) MONTH,
COUNT(DISTINCT os.USER_ID) PURCHASED_USERS
FROM USER_INFO ui
JOIN ONLINE_SALE os
ON ui.USER_ID = os.USER_ID
WHERE YEAR(ui.JOINED) = '2021' AND os.SALES_AMOUNT > 0
GROUP BY YEAR, MONTH
),
-- 2021 년에 회원가입한 회원ID
TOTAL_USER AS (
SELECT USER_ID
FROM USER_INFO
WHERE YEAR(JOINED) = '2021'
GROUP BY USER_ID
)
SELECT
pd.YEAR,
pd.MONTH,
pd.PURCHASED_USERS,
ROUND(pd.PURCHASED_USERS / (SELECT COUNT(USER_ID) FROM TOTAL_USER)
,1) PUCHASED_RATIO
FROM PURCHASED_DATA pd;
상품을 구매한 회원수
를 찾기 위해 USER_INFO
테이블와 ONLINE_SALE
테이블 이너조인상품을 구매한 회원수
찾기
COUNT(DISTINCT os.USER_ID)
를 통해 중복제거상품을 구매한 회원의 비율
pd.PURCHASED_USERS / (SELECT COUNT(USER_ID) FROM TOTAL_USER)
2021년에 가입한 전체 회원 수
가 필요하기 때문에 WITH
절 임시테이블로 조회하여 비율 구하기테이블에서 조회수가 가장 높은 중고거래 게시물에 대한 첨부파일 경로를 조회
하는 SQL문을 작성SELECT CONCAT('/home/grep/src/', A.BOARD_ID,'/',B.FILE_ID,B.FILE_NAME,B.FILE_EXT) AS FILE_PATH
FROM USED_GOODS_BOARD A JOIN USED_GOODS_FILE B
ON A.BOARD_ID = B.BOARD_ID
WHERE A.VIEWS IN (SELECT MAX(VIEWS) FROM USED_GOODS_BOARD)
ORDER BY FILE_ID DESC;
CONCAT
으로 경로 지정해주기JOIN
WHERE IN (MAX)
String, Date 카테고리에 있어서 풀어봤는데, 풀어보니까 String 주제에 더 가까운 문제 였네요 ,,!
SELECT
x
, y
, z
, CASE
WHEN x + y > z AND x + z > y AND y + z > x THEN 'Yes'
ELSE 'No'
END AS `triangle`
FROM
Triangle
CASE
구문을 이용해서 삼각형 조건에 맞으면 Yes
를 출력
문제 찾기가 어렵다..
09:00부터 19:59까지, 각 시간대별로 입양이 몇 건이나 발생했는지 조회하는 SQL문을 작성
SELECT HOUR(DATETIME) AS HOUR, COUNT(ANIMAL_ID) AS COUNT
FROM ANIMAL_OUTS
GROUP BY HOUR(DATETIME)
HAVING HOUR >= 9 AND HOUR <= 19
ORDER BY HOUR
HOUR(date)
함수 사용해서 시간만 추출
HAVING
사용해서 9<= HOUR <=19까지 필터링ORDER BY HOUR
SELECT
CASE
WHEN MOD(id, 2) = 1 AND id = (SELECT MAX(id) FROM Seat) THEN id
WHEN MOD(id, 2) = 1 THEN id+1
ELSE id-1
END AS id,
student
FROM Seat
ORDER BY id;
홀수이자 맨 마지막
, 홀수
, 짝수
로 나눠서 해결: CASE WHEN
SELECT MAX(id) FROM Seat
MOD(id, 2) = 1
기초기초 내용이지만,! WHEN THEN절 뒤에
,
붙이지 않기,,ㅎ
select round(count(customer_id)/(select count(distinct customer_id) from delivery), 4)*100 as immediate_percentage
from delivery
where order_date = customer_pref_delivery_date
and (customer_id, order_date) in (select customer_id, min(order_date) from delivery group by customer_id)
min()
을 이용해서 각 고객의 첫 주문 찾기ECOLI_DATA
테이블이 있을 때, 대장균의 사이즈에 따라서 기준에 분류된 대로 COLONY_NAME
정보 출력하기WITH TMP AS (
SELECT ID,
PERCENT_RANK() OVER
(ORDER BY SIZE_OF_COLONY DESC) AS SIZE_RANK
FROM ECOLI_DATA
)
SELECT ID,
CASE
WHEN SIZE_RANK <= 0.25 THEN 'CRITICAL'
WHEN SIZE_RANK <= 0.50 THEN 'HIGH'
WHEN SIZE_RANK <= 0.75 THEN 'MEDIUM'
ELSE 'LOW'
END AS COLONY_NAME
FROM TMP
ORDER BY ID
PERCENT_RANK() OVER
과 WITH
문을 통해 대장균 상위 % 정보를 가진 임시 테이블 생성하기CASE
문을 통해 조건에 명시된 대로 COLONY_NAME
출력하기
THEN
뒤에 문자열 사용 시'
붙이기!
REST_REVIEW
테이블이 있을 때, 리뷰를 가장 많이 작성한 회원의 리뷰들을 조회하는 SQL 문 작성하기WITH TMP AS(
SELECT MEMBER_ID
, COUNT(*) `CNT`
, RANK() OVER (ORDER BY COUNT(*) DESC) AS RNK
, REVIEW_DATE
, REVIEW_TEXT
FROM REST_REVIEW
GROUP BY MEMBER_ID
)
SELECT B.MEMBER_NAME, A.REVIEW_TEXT, DATE_FORMAT(A.REVIEW_DATE, '%Y-%m-%d') `REVIEW_DATE`
FROM REST_REVIEW A
JOIN MEMBER_PROFILE B USING(MEMBER_ID)
JOIN TMP C USING(MEMBER_ID)
WHERE C.RNK = 1
ORDER BY A.REVIEW_DATE ASC, A.REVIEW_TEXT ASC
WITH
함수와 RANK
함수를 통해 리뷰를 작성한 개수 순서대로 순위를 매긴 임시 테이블(TMP
)을 만듦REST_REVIEW
테이블과 MEMBER_PROFILE
, TMP
테이블을 조인함TMP.RNK
의 값이 1인 데이터들만 출력USED_GOODS_BOARD
테이블에서 2022년 10월 5일
에 등록된 중고거래 게시물의 게시글 ID, 작성자 ID, 게시글 제목, 가격, 거래상태를 조회하는 SQL문을 작성SELECT
BOARD_ID
, WRITER_ID
, TITLE
, PRICE
, CASE
WHEN STATUS = 'SALE' THEN '판매중'
WHEN STATUS = 'RESERVED' THEN '예약중'
WHEN STATUS = 'DONE' THEN '거래완료'
END STATUS
FROM
USED_GOODS_BOARD
WHERE
CREATED_DATE = '2022-10-05'
WHEN
절을 사용해서 조건 분기 나눠주기!SELECT
ugu.USER_ID,
ugu.NICKNAME,
CONCAT(ugu.CITY," ",ugu.STREET_ADDRESS1," ",ugu.STREET_ADDRESS2) '전체주소',
CONCAT(LEFT(ugu.TLNO, 3), '-', MID(ugu.TLNO, 4, 4), '-', RIGHT(ugu.TLNO, 4)) '전화번호'
FROM USED_GOODS_USER ugu
INNER JOIN
(
SELECT WRITER_ID
FROM USED_GOODS_BOARD
GROUP BY WRITER_ID
HAVING COUNT(WRITER_ID) > 2
) sub
ON ugu.USER_ID = sub.WRITER_ID
ORDER BY USER_ID DESC;
중고 거래 게시물을 3건 이상 등록한 사용자
찾기xxx-xxxx-xxxx
전화번호 형태를 만들기 위해 LEFT()
MID()
RIGHT()
사용
LEFT()
데이터의 왼쪽을 시작점으로 INDEX 까지 가져옴MID()
데이터의 시작INDEX
부터 시작+다음 INDEX
까지 가져옴RIGHT()
데이터의 오른쪽을 시작점으로 INDEX 까지 가져옴
DATE_FORMAT
WHEN