본문 바로가기

[공부] SQL

[SQL 코딩테스트] 해커랭크 Advanced Select 정답

The PADS
⏰ 11:26

 

CONCAT 안에 COUNT 같은걸 넣고, 뒤에서 GROUP BY로 묶어줘도 문제가 없다는 걸 처음 알았다!

SELECT CONCAT(NAME, '(', LEFT(OCCUPATION,1), ')') AS A
FROM OCCUPATIONS
ORDER BY 1
;

SELECT CONCAT('There are a total of ', COUNT(OCCUPATION), ' ', LOWER(OCCUPATION), 's.') AS A
FROM OCCUPATIONS
GROUP BY OCCUPATION
ORDER BY COUNT(OCCUPATION), OCCUPATION
;

 

Type of Triangle
⏰ 7:30

 

지난번에 리트코드인가에서 금방 풀었던 문제인데, CASE WHEN 구문 내에서 어떤 조건이 먼저 와야 하는지 헷갈려서 시간이 조금 더 걸렸다.

SELECT CASE WHEN A = B AND B = C THEN 'Equilateral'
            WHEN A+B <= C OR A+C <= B OR B+C <= A THEN 'Not A Triangle'
            WHEN A = B OR B = C OR A = C THEN 'Isosceles'
            ELSE 'Scalene' END AS TRI_TYPE
FROM TRIANGLES

 

Occupations
⏰ 20:30

 

행과 열을 바꾸는 과제가 주어져 처음 시도해봤다!

처음에 MAX 함수 같은 건 쓸 생각도 못하고 이것저것 해보고 있었는데, 게시판과 챗GPT의 도움을 받아 풀었다.

1) RANK 함수를 사용해 각 이름을 (각 직업 내에서 알파벳 순으로 정렬해) 하나의 행으로 묶어줄 임의의 열을 추가한다.

2) WITH 구문으로 묶어낸다.

3) 본쿼리에서 RANK 열로 GROUP BY 해준 뒤, SELECT에서 집계함수를 쓰지 않으면 오류가 나므로 MAX 함수로 덮어씌워준다.

 

난 아직도 MAX가 어렵다... 왜 저기서 MAX를 꼭 써야 하는건지 아직도 명확히 이해는 안됨!

GROUP BY를 써서 묶었는데 값이 하나 이상이라 딱 하나만 보여줘야 해서 강제로 집계함수를 써야만 하는걸로... 일단 외워본다.

WITH CTE AS (
SELECT NAME, OCCUPATION, 
       RANK() OVER(PARTITION BY OCCUPATION ORDER BY NAME) AS RANKS
FROM OCCUPATIONS )

SELECT MAX(IF(OCCUPATION = 'Doctor', NAME, NULL)) AS Doctor,
       MAX(IF(OCCUPATION = 'Professor', NAME, NULL)) AS Professor,
       MAX(IF(OCCUPATION = 'Singer', NAME, NULL)) AS Singer,
       MAX(IF(OCCUPATION = 'Actor', NAME, NULL)) AS Actor
FROM CTE 
GROUP BY RANKS

 

Binary Tree Nodes
⏰ 8:24

 

표로 보면 너무너무 헷갈리는 부모자식 트리(맘대로 이름 붙이기)...

셀프조인 할 때 ON절에서 B1과 B2의 순서를 거꾸로 해서 NODE와 PARANTS를 붙여주면 상대적으로 조금 더 쉽게 파악할 수 있다.

 

 

< 예를 들면 이렇게...

아래 코드대로 전체(*)를 SELECT 해보면 이렇게 나온다. 

 

그러면 세번째줄(9행)과 같이 1의 엄마는 2, 2의 엄마는 4,

왼쪽에 새끼가 없는 애는 LEAF,

맨 오른쪽에 엄마가 없는 애는 ROOT,

SELECT로 뽑아야 하는 건 오른쪽의 B2.N 값이라는게

 

직관적으로 보인다.

 

 

 

 

SELECT DISTINCT B2.N, CASE WHEN B1.P IS NULL THEN 'Leaf'
             WHEN B2.P IS NULL THEN 'Root'
             ELSE 'Inner' END AS TYPE
FROM BST B1
     RIGHT JOIN BST B2
     ON B2.N = B1.P
ORDER BY 1

 

New Companies
⏰ 25:12

 

아니... 샘플 데이터에 테이블 다섯개 주고 예시에서 각 테이블에 각각 다른 값 있는것처럼 보여줘서 다섯개 테이블 다 조인해야하는건줄 알고 열심히 짰는데 아무리 해도 정답이 안나와서 게시판 살펴보니 그냥 테이블 두개만 써서 간단히 풀어도 되는 거였다. 해커랭크 문제 질이 왜 떨어진다고 하는지 알겠어! 

 

SELECT COMPANY_CODE, FOUNDER, 
       COUNT(DISTINCT lead_manager_code), 
       COUNT(DISTINCT senior_manager_code), 
       COUNT(DISTINCT manager_code), 
       COUNT(DISTINCT employee_code)
FROM Company C
     RIGHT JOIN Employee  E
     USING (company_code)
GROUP BY 1,2
ORDER BY 1 ASC