HackerRank


1.1. Sub-String

input:

name, occupation
Ashley Professor
Samantha Actor
Julia Doctor
Britney Professor
Maria Professor
Meera Professor
Priya Doctor
Priyanka Professor
Jennifer Actor
Ketty Actor
Belvet Professor
Naomi Professor
Jane Singer
Jenny Singer
Kristeen Singer
Christeen Singer
Eve Actor
Aamina Doctor

output:

Samantha(D)
Julia(A)
Maria(A)
Meera(S)

select
        name||'('||substr(occupation,1,1)||')'
  from OCCUPATIONS
;  

1.2. Pivot

input:

name, occupation
Ashley Professor
Samantha Actor
Julia Doctor
Britney Professor
Maria Professor
Meera Professor
Priya Doctor
Priyanka Professor
Jennifer Actor
Ketty Actor
Belvet Professor
Naomi Professor
Jane Singer
Jenny Singer
Kristeen Singer
Christeen Singer
Eve Actor
Aamina Doctor

output:

doc,pro,sing,act Jenny, Ashley, Meera, Jane
Samantha, Christeen, Priya, Julia
NULL, Ketty, NULL, Maria

with wocc as (
    select  case 
                when occupation = 'Doctor' then name 
                else Null
            end as doc
            ,case 
                when occupation = 'Professor' then name 
                else Null
            end as pro
            ,case 
                when occupation = 'Singer' then name 
                else Null
            end as sing
            ,case 
                when occupation = 'Actor' then name 
                else Null
            end as act
     from OCCUPATIONS
 )
 select * 
 from (
     select d.doc, p.pro, s.sing, a.act
     from
             (select row_number() over (order by sub.doc) col, sub.doc from wocc sub) d
            ,(select row_number() over (order by sub.pro) col, sub.pro from wocc sub) p
            ,(select row_number() over (order by sub.sing) col, sub.sing from wocc sub) s
            ,(select row_number() over (order by sub.act) col, sub.act from wocc sub) a
    where d.col = p.col
      and p.col = s.col
      and s.col = a.col
 )
 where rownum < (select cnt
                 from (
                     select occupation, count(*) as cnt
                     from OCCUPATIONS
                     group by occupation
                     order by 2 desc
                     )
                where rownum = 1)+1
;                

1.3. Hierarchical Table

input:

child, parent
1,2
3,2
6,8
9,8
2,5
8,5
5,null

input:

1 Leaf
2 Inner
3 Leaf
5 Root
6 Leaf
8 Inner
9 Leaf

select 
       N
     , case
            when CONNECT_BY_ISLEAF = 1 then 'Leaf'
            when CONNECT_BY_ISLEAF = 0 and P is null then 'Root'
            else 'Inner'
      end
from BST T1
start with P is null
connect by prior N = P
order by N
;


1.4. Join Table

input:

COMPANY
c_code, founder
C1, Monika
C2, Samantha

LEAD_MANAGER
l_m_code, c_code
LM1, C1
LM2, C2

SENIOR_MANAGER
s_m_code, l_m_code, c_code
SM1, LM1, C1
SM2, LM1, C1
SM3, LM2, C2

MANAGER
m_code, s_m_code, l_m_code, c_code
M1, SM1, LM1, C1
M2, SM3, LM2, C2
M3, SM3, LM2, C2

EMPLOYEE
s_m_code, l_m_code, c_code
E1, M1, SM1, LM1, C1
E2, M1, SM1, LM1, C1
E3, M2, SM3, LM2, C2
E4, M3, SM3, LM2, C2

output:

C1 Monika 1 2 1 2
C2 Samantha 1 1 2 2

select e.company_code, founder
     , count(distinct e.lead_manager_code)
     , count(distinct e.senior_manager_code) 
     , count(distinct e.manager_code)
     , count(distinct e.employee_code )
from (select distinct company_code, founder from Company) C
left outer join (select distinct lead_manager_code, company_code from Lead_Manager) LM
 on C.company_code = LM.company_code
left outer join (select distinct senior_manager_code, lead_manager_code, company_code from Senior_Manager) SM
 on LM.lead_manager_code = SM.lead_manager_code
left outer join (select distinct manager_code, senior_manager_code, lead_manager_code, company_code from Manager) M
 on SM.senior_manager_code = M.senior_manager_code
left outer join (select distinct employee_code, manager_code, senior_manager_code, lead_manager_code, company_code from Employee) E
 on M.manager_code = E.manager_code
group by e.company_code, founder
order by 1
;

1.5. Max, Min values

input:

DEF, ABC, PQRS, WXY

output:

ABC 3
PQRS 4

with wstation as 
(select  city
       , length(city) as lencity
from station
order by 2, 1
)
, w2station as
(select city, lencity
  from (select row_number() over (partition by lencity order by city) as rnum
             , city
             , lencity
        from wstation
        )
where rnum < 2
)
select *
from w2station
where (lencity = (select min(lencity) from wstation)
       or lencity = (select max(lencity) from wstation)
      ) 
;

1.6. Join table2

input:

STUDENTS
ID, Name, Marks
1, Julia, 88
2, Samantha, 68
3, Maria, 99
4, Scarlet, 78
5, Ashley, 63
6, Jane, 81

GRADES Grade, Min_Mark, Max_Mark
1, 0, 9
2, 10, 19
3, 20, 29
4, 30, 39
5, 40, 49
6, 50, 59
7, 60, 69
8, 70, 79
9, 80, 89
10, 90, 100

output:

lower than 8, name is null

Maria 10 99
Jane 9 81
Julia 9 88
Scarlet 8 78
NULL 7 63
NULL 7 68

select case
           when g.grade > 7 then s.name
           else NULL
       end as name
        , g.grade
        , s.marks
from STUDENTS s
inner join GRADES g 
  on s.marks between g.min_mark and g.max_mark
order by g.grade desc, name
;

1.7. Group by & Having

input:

HACKERS
h_id, name
5580, Rose
8439, Angela
27205, Frank
52243, Patrick
52348, Lisa
57645, Kimberly
77726, Bonnie
83082, Michael
86870, Todd
90411, Joe

DIFFICULTY
d_level, score
1, 20
2, 30
3, 40
4, 60
5, 80
6, 100
7, 120

CHALLENGE c_id, h_id, d_level
4810, 77726, 4
21089, 27205, 1
36566, 5580, 7
66730, 52243, 6
71055, 52243, 2

SUBMISSION s_id, h_id, c_id, score 68628, 77726, 36566, 30
65300, 77726, 21089, 10
40326, 52243, 36566, 77
8941, 27205, 4810, 4
83554, 77726, 66730, 30

97397, 90411, 66730, 100
84162, 83082, 4810, 40
97431, 90411, 71055, 30

output:

90411 Joe

with wsub as (
select h.hacker_id, h.name, count(distinct s.challenge_id) as cnt --, s.score
from Submissions s
left outer join Hackers h
  on s.hacker_id = h.hacker_id
left outer join Challenges c
  on s.challenge_id = c.challenge_id
left outer join Difficulty d
  on c.difficulty_level = d.difficulty_level
where s.score = d.score
  and s.score is not null
group by h.hacker_id, h.name
having count(distinct s.challenge_id) > 1
order by cnt desc, h.hacker_id 
)
select hacker_id, name
from wsub;

1.8. grouping and ranking

input:

WANDS
id, code, coins_needed, power 1, 4, 3588, 8
2, 3, 9365, 3
3, 3, 7187, 10
4, 3, 734, 8
5, 1, 6020, 8
6, 2, 6773, 3
7, 3, 9873, 10
8, 3, 7721, 8
9, 1, 1647, 8
10, 4, 504, 3
11, 2, 7587, 10
12, 5, 9897, 8
13, 3, 4651, 8
14, 2, 5408, 3
15, 2, 6018, 10
16, 4, 7710, 8
17, 2, 8798, 8
18, 2, 3312, 3
19, 4, 7651, 10
20, 5, 5689, 8

WANDS_PROPERTY code, age, is_evil
1, 45, 0 2, 40, 0
3, 4, 1
4, 20, 0
5, 17, 0

output:

9 45 1647 10
12 17 9897 10
1 20 3688 8
15 40 6018 7
19 20 7651 6
11 40 7587 5
10 20 504 5
18 40 3312 3
20 17 5689 3
5 45 6020 2
14 40 5408 1

with wsub as (
select rank() over (partition by w.power, wp.age order by w.coins_needed) as rank
     , w.power
     , wp.age
     , w.coins_needed
     , w.id
from WANDS w
inner join WANDS_PROPERTY wp
             on w.code = wp.code
            and wp.is_evil = 0  
order by  w.power desc, wp.age desc, w.coins_needed
)
select id, age, coins_needed, power
from wsub
where rank = 1
;

1.9. max인 공동 1위들은 전체 출력, 나머지는 공동 랭킹들은 제외

select c.hacker_id, h.name, count(c.challenge_id) as cnt
from hackers h
inner join challenges c
  on h.hacker_id = c.hacker_id
group by c.hacker_id, h.name
having count(c.challenge_id) = (select max(tmp1.cnt)
                from (select count(hacker_id) as cnt
                       from challenges
                     group by hacker_id
                     order by hacker_id) tmp1)
       or
         count(c.challenge_id) in ( select cnt1
        from( select hacker_id, count(challenge_id) as cnt1
            from challenges
            group by hacker_id)
        group by cnt1
        having count(cnt1) = 1)
order by count(c.challenge_id) desc, c.hacker_id
;