💥 CODEKATA
~ 96문제
오늘의 코드카타 후기 :
SQL 최대한 효율적인 코드로 짜려고 하니까 시간 진짜 오래 걸린다
96번에 너무 지쳐서 효율 1등 코드는 나중에 보는걸로
그리고,
통 계 . ….게 . .. .. . 개 싫 드 아 아 아 아 앙
95) Queries Quality and Percentage
# 내코드
WITH cnt AS (
SELECT query_name, COUNT(rating) cnt FROM queries WHERE rating < 3 GROUP BY query_name
)
SELECT
a.query_name,
ROUND(AVG(a.new), 2) AS quality,
IFNULL(ROUND((c.cnt / COUNT(a.query_name)) * 100, 2), 0) AS poor_query_percentage
FROM (
SELECT *, (rating / position) AS new
FROM queries
) a LEFT JOIN cnt c ON a.query_name = c.query_name
GROUP BY a.query_name
⇒ ⭕
나름 속도 빠른 축에 속하는데 이거보다 괜찮은 코드 있나 탐방함
# 1등코드
SELECT
query_name,
ROUND(AVG(cast(rating AS DECIMAL) / position), 2) AS quality,
ROUND(SUM(CASE WHEN rating < 3 THEN 1 ELSE 0 END) * 100 / COUNT(*), 2) AS poor_query_percentage
FROM queries
GROUP BY query_name;
# 1차 코드
SELECT a.month, t.country, COUNT(DISTINCT t.id) AS trans_count, a.approved_count, SUM(t.amount) AS trans_total_amount, a.approved_total_amount
FROM transactions t JOIN (
SELECT id, country, state, amount, DATE_FORMAT(trans_date, "%Y-%m") AS month, COUNT(*) AS approved_count, SUM(amount) AS approved_total_amount
FROM transactions
WHERE state = "approved"
GROUP BY DATE_FORMAT(trans_date, "%Y-%m"), country
) a ON DATE_FORMAT(t.trans_date, "%Y-%m") = a.month
GROUP BY a.month, t.country
⇒ ❌
DISTINCT 를 먹여도 JOIN 때문인지 id가 계속 중복값이 나와서 SUM(amount)가 안맞음 WITH 안쓰고 풀고 싶었는데, 해결을 못하겠어서 WITH씀
# 2차 코드
WITH allt AS (
SELECT id, country, state, amount, trans_date, DATE_FORMAT(trans_date, "%Y-%m") AS month, COUNT(*) AS trans_count, SUM(amount) AS trans_total_amount
FROM transactions
GROUP BY DATE_FORMAT(trans_date, "%Y-%m"), country
),
appt AS (
SELECT id, country, state, amount, DATE_FORMAT(trans_date, "%Y-%m") AS month, IFNULL(COUNT(*), 0) AS approved_count, IFNULL(SUM(amount), 0) AS approved_total_amount
FROM transactions
WHERE state = "approved"
GROUP BY DATE_FORMAT(trans_date, "%Y-%m"), country
)
SELECT a1.month, a1.country, a1.trans_count, a2.approved_count, a1.trans_total_amount, a2.approved_total_amount
FROM allt a1 JOIN appt a2 ON a1.month = a2.month AND a1.country = a2.country
⇒ ❌
답은 맞는데, 서버 테스트 결과에서 틀린게 나옴.
모두 다 approved가 하나도 없는 경우에는 아예 테이블 자체가 출력되지 않음;
# 3차 코드
WITH allt AS (
SELECT id, country, state, amount, trans_date, DATE_FORMAT(trans_date, "%Y-%m") AS month, COUNT(*) AS trans_count, SUM(amount) AS trans_total_amount
FROM transactions
GROUP BY DATE_FORMAT(trans_date, "%Y-%m"), country
),
appt AS (
SELECT id, country, state, amount, DATE_FORMAT(trans_date, "%Y-%m") AS month, COUNT(trans_date) AS approved_count, SUM(amount) AS approved_total_amount
FROM transactions
WHERE state = "approved"
GROUP BY DATE_FORMAT(trans_date, "%Y-%m"), country
)
SELECT a1.month, a1.country, a1.trans_count, IFNULL(a2.approved_count, 0) AS approved_count, a1.trans_total_amount, IFNULL(a2.approved_total_amount, 0) AS approved_total_amount
FROM allt a1 LEFT JOIN appt a2 ON a1.month = a2.month AND a1.country = a2.country
⇒ ❌
테이블 자체가 출력 안되는 건 LEFT JOIN 으로 해결하고, 아예 없는 NULL을 대비해서 IFNULL을 사용했는데, 이제 country 가 null일 때 count를 못하는 경우가 생김 하ㅣ.....ㄱ- 도저히 모르겠어서 지피티한테 물어봄
JOIN 에서 a1.country = a2.country 때문에 country 가 NULL인 경우 매칭이 안됨 → JOIN 매칭이 실패하면 a2. 테이블의 모든 컬럼은 NULL 이 되기 때문에 IFNULL 때문에 0이 나옴
라고 한다
와 여기서 JOIN 할 때 month랑만 하면 month에 다른 나라들도 다 끼는데 어떻게 해야되지; 모르겠어서 걍 지피티 답안 봄
# 최종코드
WITH allt AS (
SELECT id, country, state, amount, trans_date, DATE_FORMAT(trans_date, "%Y-%m") AS month, COUNT(*) AS trans_count, SUM(amount) AS trans_total_amount
FROM transactions
GROUP BY DATE_FORMAT(trans_date, "%Y-%m"), country
),
appt AS (
SELECT id, country, state, amount, DATE_FORMAT(trans_date, "%Y-%m") AS month, COUNT(trans_date) AS approved_count, SUM(amount) AS approved_total_amount
FROM transactions
WHERE state = "approved"
GROUP BY DATE_FORMAT(trans_date, "%Y-%m"), country
)
SELECT a1.month, a1.country, a1.trans_count, IFNULL(a2.approved_count, 0) AS approved_count, a1.trans_total_amount, IFNULL(a2.approved_total_amount, 0) AS approved_total_amount
FROM
allt a1 LEFT JOIN appt a2 ON a1.month = a2.month
AND (a1.country = a2.country OR (a1.country IS NULL AND a2.country IS NULL))
⇒ ⭕
아 IS NULL 조건을 그냥 추가만 시키면 되는구나 이런 젠장~~~
아 진짜 시간 오래걸려서 똥꼬쑈 했는데 시간 효율 별로라 슬픔…

효율 1등 코드 나중에 볼 것
# 1등코드
SELECT
LEFT(trans_date, 7) AS month,
country,
COUNT(id) AS trans_count,
SUM(state = 'approved') AS approved_count,
SUM(amount) AS trans_total_amount,
SUM((state = 'approved') * amount) AS approved_total_amount
FROM
Transactions
GROUP BY
month, country;
'Sparta > CODEKATA' 카테고리의 다른 글
| [250924] 스파르타코딩 본캠프 37일차 (1) | 2025.09.24 |
|---|---|
| [250923] 스파르타코딩 본캠프 36일차 (3) | 2025.09.23 |
| [250918] 스파르타코딩 본캠프 33일차 (0) | 2025.09.18 |
| [250917] 스파르타코딩 본캠프 32일차 (0) | 2025.09.17 |
| [250916] 스파르타코딩 본캠프 31일차 (2) | 2025.09.16 |