SQL、HackerRank、Challengsプール

10880 ワード

1.質問


💡 質問リンク
https://www.hackerrank.com/challenges/challenges/problem?isFullScreen=true&h_r=next-challenge&h_v=zen

1.1表、フィールド情報


Hackers
  • hacker_id : (interger)
  • name : (string)
  • Challenges
  • challenge_id : (integer)
  • ハッカーid:(整数)作成に挑戦する学生のid
  • 1.2問題の概要

  • ハッカーid、name、total=(総挑戦数)出力
  • チャレンジテーブルはハッカーテーブルのサブセット
  • である.
  • 総降順、hacker id昇順
  • 総額が同じ学生の記録を除く.(ただし、総額が最大の場合は含む)
    -言い換えれば、出力
  • は、total値が最大またはtotal値が唯一の学生である場合にのみ出力される.

    2.解答(1)

    -- (1) total 값이 최대인 학생
    SELECT H.HACKER_ID, H.NAME, B.TOTAL
    FROM (
        SELECT A.TOTAL, COUNT(A.TOTAL) TOTAL_COUNT
        FROM (
            SELECT HACKER_ID, COUNT(CHALLENGE_ID) TOTAL 
            FROM CHALLENGES
            GROUP BY 1
            ) A
        GROUP BY A.TOTAL
        ORDER BY 1 DESC
        LIMIT 1) B
    JOIN (
        SELECT HACKER_ID, COUNT(CHALLENGE_ID) TOTAL
        FROM CHALLENGES
        GROUP BY 1
    ) C ON B.TOTAL = C.TOTAL
    JOIN HACKERS H ON H.HACKER_ID=C.HACKER_ID
    ORDER BY 3 DESC, 1;
    
    --- (2) total 값이 유일한 학생
    SELECT H.HACKER_ID, H.NAME, B.TOTAL
    FROM (
        SELECT A.TOTAL, COUNT(A.TOTAL) TOTAL_COUNT
        FROM (
            SELECT HACKER_ID, COUNT(CHALLENGE_ID) TOTAL 
            FROM CHALLENGES
            GROUP BY 1
            ) A
        GROUP BY A.TOTAL
        HAVING TOTAL_COUNT = 1) B
    JOIN (
        SELECT HACKER_ID, COUNT(CHALLENGE_ID) TOTAL
        FROM CHALLENGES
        GROUP BY 1
    ) C ON B.TOTAL = C.TOTAL
    JOIN HACKERS H ON H.HACKER_ID=C.HACKER_ID
    ORDER BY 3 DESC, 1;
    

    2.1何か間違いがありますか

  • (1)の合計が最大の学生と(2)の合計が一意の場合の学生のクエリーを別々に組織し、接続します.
  • (2)では、total値が一意の場合のtotal値を取得し、キーとしてインラインする.
    これにより,(1)と(2)をor文に接続できず,クエリが長くなる.inner joinではなくin演算を使用する解があり、参照に供されます.
  • 2.解答(2)


    💡 ソース:
    https://techblog-history-younghunjo1.tistory.com/157?category=962943
    SELECT Hackers.hacker_id, Hackers.name, COUNT(*) AS challenges_created
    FROM Hackers
    INNER JOIN Challenges ON Hackers.hacker_id = Challenges.hacker_id
    GROUP BY Hackers.hacker_id -- hacker id가 primary key역할을 한다면, name은 빼도 될 것 같다.
    HAVING challenges_created IN (SELECT sub2.challenges_created
                                  FROM (SELECT hacker_id, COUNT(*) AS challenges_created
                                        FROM Challenges
                                        GROUP BY Challenges.hacker_id) sub2
                                  GROUP BY sub2.challenges_created
                                  HAVING COUNT(*) = 1)
        OR challenges_created = (SELECT MAX(sub1.challenges_created)
                                 FROM (SELECT COUNT(*) AS challenges_created
                                       FROM Challenges
                                       GROUP BY Challenges.hacker_id) sub1)
    ORDER BY challenges_created DESC, Hackers.hacker_id
  • チャレンジ創造(=学生ごとの総チャレンジ指数)を創造し,IN関数で条件を満たすチャレンジ創造をもたらした.
  • は、チャレンジ作成頻度を表す変数を別途作成していない.代わりに、group byと書いて、having count(*)=1で周波数についての条件文を書きました.