본문 바로가기
TIL - 프로그래밍/SQL

[해커랭크] Challenges - MySQL

by chaemj97 2023. 7. 6.
728x90

https://www.hackerrank.com/challenges/challenges/problem

 

Challenges | HackerRank

Print the total number of challenges created by hackers.

www.hackerrank.com


  • 문제
    1. 해커id, 이름, 각 학생이 만든 챌린지 수(challenges_created) 출력
    2. challenges_created 내림차순, 해커id 오름차순 정렬
    3. challenges_created가 같은 사람이 존재할 때
      • challenges_created가 최댓값이라면 출력
      • challenges_created가 최댓값이 아니라면 제외

  • 풀이

CODE1 : 요구사항 1번, 2번

-- 출력 해커id, 이름, 각 학생이 만든 챌린지 수(challenges_created)
-- sort challenges_created DESC, 해커id

SELECT Hackers.hacker_id
     , Hackers.name
     , COUNT(*) AS challenges_created
FROM Challenges
    INNER JOIN Hackers ON Challenges.hacker_id = Hackers.hacker_id
GROUP BY Hackers.hacker_id, Hackers.name
ORDER BY challenges_created DESC, HAckers.hacker_id;

CODE2 : 요구사항 3번

-- challenges_created가 최댓값 (테스트 데이터 : 50) -> 포함
SELECT MAX(challenges_created)
FROM (
    SELECT hacker_id
         , COUNT(*) AS challenges_created
    FROM Challenges
    GROUP BY hacker_id
) sub;

-- challenges_created가 최댓값이 아닌 경우 + 여러 명이 같은 값을 가지는 경우 -> 제외
-- challenges_created의 개수가 1개인 challenges_created 리스트
SELECT challenges_created
FROM (
    SELECT hacker_id
         , COUNT(*) AS challenges_created
    FROM Challenges
    GROUP BY hacker_id
) sub
GROUP BY challenges_created
HAVING COUNT(*) = 1;

CODE1에 조건을 추가해야 한다. 그룹화된 데이터에 조건은 HAVING절

SELECT Hackers.hacker_id
     , Hackers.name
     , COUNT(*) AS challenges_created
FROM Challenges
    INNER JOIN Hackers ON Challenges.hacker_id = Hackers.hacker_id
GROUP BY Hackers.hacker_id, Hackers.name
-- challenges_created가 최댓값인 경우
HAVING challenges_created = (SELECT MAX(challenges_created)
                              FROM (
                                  SELECT hacker_id
                                       , COUNT(*) AS challenges_created
                                  FROM Challenges
                                  GROUP BY hacker_id
                              ) sub)
-- challenges_created가 최댓값 X + 여러개의 값을 가지는 경우 제외하기
-- challenges_created가 1개씩 존재하는 경우
OR challenges_created IN (SELECT challenges_created
                          FROM (
                              SELECT hacker_id
                                   , COUNT(*) AS challenges_created
                              FROM Challenges
                              GROUP BY hacker_id
                          ) sub
                          GROUP BY challenges_created
                          HAVING COUNT(*) = 1)
ORDER BY challenges_created DESC, HAckers.hacker_id;

중복 코드가 존재한다. WITH절로 코드 줄이기

WITH절은 가상테이블을 생성할 수 있다.

https://chaemi720.tistory.com/331

 

[SQL] WITH 절

WITH 절 임시테이블 or 가상 테이블 반복되는 서브쿼리 블록을 하나의 WITH 절 블록으로 만들어서 사용 가능 한 번 실행할 쿼리문 내 정의하여 해당 쿼리 안에서만 실행 WITH 절 사용법 # 가상 테이블

chaemi720.tistory.com

 

  • 최종 코드
# counter라는 가상 테이블 만들기
WITH counter AS (
    SELECT Hackers.hacker_id
         , Hackers.name
         , COUNT(*) AS challenges_created
    FROM Challenges
        INNER JOIN Hackers ON Challenges.hacker_id = Hackers.hacker_id
    GROUP BY Hackers.hacker_id, Hackers.name 
)

SELECT counter.hacker_id
     , counter.name
     , counter.challenges_created
FROM counter
WHERE challenges_created = (SELECT MAX(challenges_created) FROM counter)
OR challenges_created IN (SELECT challenges_created
                          FROM counter
                          GROUP BY challenges_created
                          HAVING COUNT(*) = 1)
ORDER BY counter.challenges_created DESC, counter.hacker_id;
728x90
반응형

댓글