[HackerRank lv6] SQL๋ฌธ์ œํ’€์ด - Challenges

๋ฐํ”„ยท2023๋…„ 11์›” 23์ผ
1

SQL๋ฌธ์ œํ’€์ด

๋ชฉ๋ก ๋ณด๊ธฐ
3/7

๐Ÿ‘‰ ๋ฌธ์ œ ๋ฐ”๋กœ๊ฐ€๊ธฐ(HackerRank)

# ๋ฌธ์ œ

Q. hackers ํ…Œ์ด๋ธ”๊ณผ challenges ํ…Œ์ด๋ธ”์—์„œ ํ•ด์ปค๋ณ„๋กœ ์ถœ์ œํ•œ challenge ์ˆ˜๋ฅผ ์ถœ๋ ฅํ•˜๋ผ. challenge ์ˆ˜๊ฐ€ ๊ฒน์น  ๋•Œ challenge ์ˆ˜๊ฐ€ ์ตœ๊ณ ๋ผ๋ฉด ์ „๋ถ€ ์ถœ๋ ฅํ•˜๋ผ. challenge ์ˆ˜๊ฐ€ ๊ฒน์น˜๋Š”๋ฐ ์ตœ๊ณ ๊ฐ€ ์•„๋‹ˆ๋ผ๋ฉด ์ „๋ถ€ ์ œ๊ฑฐํ•˜๋ผ

ex)

INPUT OUTPUT
idchallenges
a10
b10
c9
d8
e8
f7
idchallenges
a10
b10
c9
e7

์„ค๋ช…์„ ๊ฐ„๋‹จํ•˜๊ฒŒ ์œ„ํ•ด ์ƒ๋žตํ–ˆ์ง€๋งŒ
์‹ค์ œ๋กœ๋Š” hacker_id, hacker_name, challenge ์ˆ˜๋ฅผ ์ถœ๋ ฅํ•ด์•ผํ•œ๋‹ค.

์กฐ๊ฑด๋ณ„๋กœ ์ถœ๋ ฅ์„ ๋‹ฌ๋ฆฌํ•ด์•ผํ•˜๋Š” ๊ดด๋ž„ํ•œ ๋ฌธ์ œ์ด๋‹ค.
windowํ•จ์ˆ˜ ์‚ฌ์šฉ์ด ํ•„์ˆ˜์ ์ด๋‹ค. ๋ชจ๋ฅธ๋‹ค๋ฉด ์•„์˜ˆ ํ’€ ์ˆ˜๊ฐ€ ์—†๋‹ค.
์ง€๋‚œ ๊ฐ€๋น„์•„์ฝ”๋”ฉํ…Œ์ŠคํŠธ ๋ฌธ์ œ์—์„œ ๊ฑฐ์˜ ๋™์ผํ•œ ์œ ํ˜•์„ ํ’€์–ด๋ณด์•„์„œ ์–ด๋–ป๊ฒŒ๋“  ํ’€์–ด๋‚ธ ๊ฒƒ ๊ฐ™๋‹ค.

# ์ •๋‹ต

# mysql
select 
    h.hacker_id
    , h.name
    , handc.total_number
from 
    hackers h
    , (
        select 
            h.hacker_id
            , count(*) total_number
        from
            hackers h
            , challenges c
        where 
            h.hacker_id = c.hacker_id
        group by 
            h.hacker_id
    ) handc
    , (
        select 
            count(*) max_number
        from 
            hackers h
            , challenges c
        where 
            h.hacker_id = c.hacker_id
        group by 
            h.hacker_id
        order by 1 desc
        limit 1
    ) max_count
where
    h.hacker_id = handc.hacker_id
    and handc.total_number = max_count.max_number
union all ###############################################
select 
    hcrn.hacker_id
    , h.name
    , hcrn.total_number
from
    hackers h
    , (    
        select
            count(*) over(partition by rnk) cnt
            , hacker_id
            , total_number
        from
            (
                select
                    dense_rank() over(order by count(*) desc) rnk
                    , h.hacker_id
                    , count(*) total_number
                from
                    hackers h
                    , challenges c
                where 
                    h.hacker_id = c.hacker_id
                group by 
                    h.hacker_id
            ) hc
        where rnk > 1
    ) hcrn
where 
    h.hacker_id = hcrn.hacker_id
    and cnt = 1
order by 
    3 desc
    , 1
;
  1. challenge ์ˆ˜๊ฐ€ ์ตœ๋Œ€์ธ ๋ถ€๋ถ„(์ˆ˜๊ฐ€ ๊ฒน์ณ๋„ ์ถœ๋ ฅ)
    • name์„ ์–ป๊ธฐ ์œ„ํ•œ hackers
    • hackers์™€ challenges๋ฅผ ์กฐ์ธํ•˜์—ฌ group by ํ•œ ํ…Œ์ด๋ธ”
    • ์ตœ๋Œ€ ์ˆ˜๋ฅผ ๊ฐ€์ง„ one์ปฌ๋Ÿผ one๋ฐ์ดํ„ฐ ํ…Œ์ด๋ธ”
  2. challenge ์ˆ˜๊ฐ€ ์ตœ๋Œ€๊ฐ€ ์•„๋‹Œ ๋ถ€๋ถ„(์ˆ˜๊ฐ€ ๊ฒน์น˜๋Š” ๊ฒƒ์€ ์ œ๊ฑฐ)
    • name์„ ์–ป๊ธฐ ์œ„ํ•œ hackers
    • challenge ์ˆ˜๋ฅผ ๋žญํฌํ•˜๊ณ  ์ค‘๋ณต๋˜๋Š” ๊ฐฏ์ˆ˜๋ฅผ ๊ณ„์‚ฐํ•œ ํ…Œ์ด๋ธ”

# ์ตœ์ ํ™”

select 
    hacker_id
    , name
    , total_number
from 
    (
        select 
            h.hacker_id
            , h.name
            , count(*) total_number
            , rank() over(order by count(h.hacker_id) desc) rnk
        from
            hackers h
            , challenges c
        where 
            h.hacker_id = c.hacker_id
        group by 
            h.hacker_id, h.name
    ) handc
where 
    rnk = 1
union all
select 
    hacker_id
    , name
    , total_number
from
    (    
        select
            h.hacker_id
            , h.name
            , count(*) total_number
            , dense_rank() over(order by count(*) desc) rnk
            , count(count(*)) over(partition by count(*)) cnt
        from
            hackers h
            , challenges c
        where 
            h.hacker_id = c.hacker_id
        group by 
            h.hacker_id, h.name
    ) hc
where 
    cnt = 1
    and rnk > 1
order by 
    3 desc
    , 1
;

์œˆ๋„์šฐ ํ•จ์ˆ˜์˜ ๋™์ž‘๋ฐฉ์‹์„ ์ดํ•ดํ•˜๋ฉด ์œ„์™€ ๊ฐ™์€ ์ฟผ๋ฆฌ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.
์œˆ๋„์šฐ ํ•จ์ˆ˜๋„ ๊ธฐ๋ณธ์ ์œผ๋กœ group by์˜ ์ปฌ๋Ÿผ๊ตฌ๋ถ„์„ ๋”ฐ๋ผ๊ฐ€๊ธฐ ๋•Œ๋ฌธ์— ๋‹ค์‹œ ๊ทธ ์•ˆ์—์„œ count(count(*))๋ฅผ ํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์ค‘๋ณต์ˆ˜๋ฅผ ๊ตฌํ•œ๋‹ค.

# ๊ดด๋ฌผ์˜ ๋‹ต๋ณ€

discussionํƒญ์—์„œ ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค์˜ ๋‹ต๋ณ€์„ ๋ณด๋˜ ์ค‘ ์—„์ฒญ๋‚˜๊ฒŒ ์ตœ์ ํ™”๋œ ์ฟผ๋ฆฌ๋ฅผ ๋ฐœ๊ฒฌํ–ˆ๋‹ค.
๋น„์Šทํ•œ ์œ ํ˜•์˜ ๋ฌธ์ œ๋“ค์„ ํ’€ ๋•Œ ์—„์ฒญ๋‚˜๊ฒŒ ๋„์›€์ด ๋  ๋“ฏ ํ•œ๋ฐ
๊ตฌ๋ฌธ์„ ์ค„์ด๋Š”๊ฒŒ ๋ฏธ์นœ๋“ฏ์ด ํšจ์œจ์ ์ด๋ผ ์˜คํžˆ๋ ค ์ฒ˜์Œ๋ณด๋Š” ์‚ฌ๋žŒ์€ '์ด๊ฒŒ ๋ญ์ง€' ์‹ถ์„์ˆ˜ ์žˆ๊ฒ ๋‹ค...

์„œ๋ธŒ์ฟผ๋ฆฌ๋ฅผ ๊ฑฐ์˜ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  windowํ•จ์ˆ˜ ์•ˆ์— ์ง‘๊ณ„ํ•จ์ˆ˜๋ฅผ ๋„ฃ์–ด์„œโ˜ ๏ธ '์ค‘๋ณต ๋œ ์นด์šดํŠธ'๋ฅผ ์„ธ๊ณ 
WHERE ์ ˆ์— ์ค‘๋ณต์กฐ๊ฑด์— NOT์„ ๊ฑธ์–ด์„œโ˜ ๏ธ ์ตœ๊ณ  ์ˆ˜ ์ผ๋•Œ์™€ ์•„๋‹๋•Œ๋ฅผ ์ „๋ถ€ ์•„์šฐ๋ฅด๋Š” ์กฐ๊ฑด์„ ์„ค์ •ํ–ˆ๋‹ค.

์ •๋ง ๋˜‘๋˜‘ํ•œ ์‚ฌ๋žŒ์€ ๋งŽ์€ ๊ฒƒ ๊ฐ™๋‹ค... ๋ถ„๋ฐœํ•˜์ž๐Ÿ˜ญ

SELECT 
    hacker_id
    , name
    , totalcount
FROM
    (
        SELECT 
            Hackers.hacker_id,
            name, 
            COUNT(challenge_id) AS totalcount,
            COUNT(COUNT(challenge_id)) OVER (PARTITION BY COUNT(challenge_id)) as dupes,
            MAX(COUNT(challenge_id)) OVER () as max
        FROM 
            Hackers 
            LEFT JOIN Challenges USING(hacker_id)
        GROUP BY 
            Hackers.hacker_id, name
    ) B
WHERE 
    NOT (dupes >1 && totalcount < max)
ORDER BY 
    totalcount desc
    , hacker_id
profile
์ •๋ณด์˜ ํ™์ˆ˜๋ฅผ ๊ธฐ๋กํ•˜๋Š” ๋ฐํ”„์˜ ๋กœ๊ทธ

0๊ฐœ์˜ ๋Œ“๊ธ€

๊ด€๋ จ ์ฑ„์šฉ ์ •๋ณด