SQL 문제풀이 복습
문제 링크
join을 써서
날짜가 하루씩 증가 + 동시에 amount가 증가하는지 여부를 판단하고
window 함수를 써서 그루핑의 기준이 될 group_id를 만드는 것이 포인트.
(join만 쓰거나, window함수만 쓰면 해결하기 어렵다.)
group_id를 만들 때 date_sub 인자로 window함수를 넣는 것까지
여러 가지 개념과 테크닉을 다 활용해야 하는 아주 좋은 문제라고 생각!
SELECT customer_id,
MIN(td1) AS "consecutive_start",
MAX(td2) AS "consecutive_end"
FROM (
SELECT t1.transaction_id,
t1.customer_id,
t1.transaction_date AS "td1",
t2.transaction_date AS "td2",
RANK() over(partition BY t1.customer_id ORDER BY t1.transaction_date) AS "rank",
date_sub(t1.transaction_date, INTERVAL rank() over(partition BY t1.customer_id ORDER BY t1.transaction_date) DAY) AS "group_id"
FROM Transactions t1
JOIN Transactions t2
ON t1.customer_id = t2.customer_id
AND t1.amount < t2.amount
AND t1.transaction_date = date_sub(t2.transaction_date, INTERVAL 1 DAY)) a
GROUP BY customer_id,
group_id
HAVING COUNT(*) >= 2
ORDER BY 1;
문제 링크
least/greatest를 활용하는 문제.
모든 친구들의 경우의 수(all_friends)를 만들기 위해
least/greatest와 greatest/least를 union하는 게 포인트.
(union all을 하면 숫자가 뻥튀기되므로 안됨)
WITH all_friends
AS (SELECT LEAST(user1, user2) AS "user1",
GREATEST(user1, user2) AS "user2"
FROM Friends
UNION
SELECT GREATEST(user1, user2) AS "user1",
LEAST(user1, user2) AS "user2"
FROM Friends)
SELECT user1,
Round(100.0 * Count(*) / (SELECT Count(DISTINCT user1)
FROM all_friends), 2) AS
"percentage_popularity"
FROM all_friends
GROUP BY 1
ORDER BY 1;
문제 링크
불리언 연산에 관한 문제.
sum함수 뒤에 정수/실수형 컬럼만 올 수 있는 건 아니다.
content like 등으로 불리언 연산을 수행한 다음 합계를 내면
특정 단어가 몇 번 쓰였는지 셀 수 있음.
SELECT 'bull' AS "word",
SUM(content LIKE '% bull %') AS "count"
FROM Files
UNION
SELECT 'bear',
SUM(content LIKE '% bear %')
FROM Files;