프로그래머스 SQL 문제도 다 풀었고 hackerrank로 넘어갑니다.

문제

https://www.hackerrank.com/challenges/the-pads/problem

 

The PADS | HackerRank

Query the name and abbreviated occupation for each person in OCCUPATIONS.

www.hackerrank.com

 

풀이

우선 두 가지 방식으로 출력이 진행되어야 한다.

1. Name(A)와 같은 (직업 이니셜)의 형태가 포함된 출력 (ex. Ashely(P), Christeen(P))

주의할 점은 직업의 수가 4개만 존재한다는 것이다. [Doctor Professor Singer Actor]

SELECT concat(name,'(',substr(Occupation,1,1),')')  as name
FROM OCCUPATIONS
ORDER BY name;

 

간단하게 substr과 concat을 사용해서 만들어주면 된다.

 

2. There are a total of [occupation_count] [occupation] s. 의 형태로 직업의 count를 출력할 것.

여기서 주의할 점은 occupations가 기존에는 Doctor와 같이 첫 글자가 대문자이나 출력값에서는
모두 소문자로 출력해야 하는 점이다. (이 부분이 가장 어려웠다..)

WITH CTE2 AS (
    SELECT  count(*) as c, occupation
    FROM OCCUPATIONS
    GROUP BY Occupation
    ORDER BY 1 
)
, CTE3 AS (
    SELECT CONCAT('There are a total of ',c,' ',lower(occupation),'s.') as name
    FROM CTE2
)
SELECT name
FROM CTE3;

 

GROUP BY를 사용해서 각 직업별 count를 계산하고 이를 concat을 활용해서 문장의 형태로 만들어주었다.

문제

Write a solution to fix the names so that only the first character is uppercase and the rest are lowercase.

Return the result table ordered by user_id.

첫문자는 대문자로, 그리고 나머지 문자들은 소문자로 변경해야한다.

user_id로 정렬한다.

 

테이블 & 예제

[Users]

+----------------+---------+
| Column Name    | Type    |
+----------------+---------+
| user_id        | int     |
| name           | varchar |
+----------------+---------+
user_id is the primary key (column with unique values) for this table.
This table contains the ID and the name of the user. The name consists of only lowercase and uppercase characters.

 

[Example]

Input: 
Users table:
+---------+-------+
| user_id | name  |
+---------+-------+
| 1       | aLice |
| 2       | bOB   |
+---------+-------+
Output: 
+---------+-------+
| user_id | name  |
+---------+-------+
| 1       | Alice |
| 2       | Bob   |
+---------+-------+

 

풀이

우선 풀이 이전에 몇가지 새로 알게된 개념들을 짚고 넘어간다.

[CONCAT]

둘 이상의 문자열 값을 연결하거나, 조인하는 문자열을 반환한다. 인수로는 2개 이상 254개 이하로 사용 가능하다고 한다.

만약 null이 나온다면 임시적으로 빈 문자열로 변환 후 연결한다.

[GROUP_CONCAT]

그룹으로 묶어서 연결하는 방법이다. => 하나의 열을 묶어서 문자열로 출력한다.
(후에 문제가 나와서 추가합니다.)
group_concat 시에 열을 묶는 순서를 지정하기위해 ORDER BY의 사용이 가능합니다. 아래는 예시코드입니다.

GROUP_CONCAT(DISTINCT(product) ORDER BY product) AS products

 

참고: https://donghodazzi.tistory.com/141

 

[Mysql] 문자열 합치기(CONCAT, GROUP_CONCAT)

CONCAT 둘 이상의 문자열 값을 엔드투엔드 방식으로 연결하거나 조인한 결과 문자열을 반환합니다. 인수는 2개 이상 254개 이하로 사용 가능하다. CONCAT(값1, 값2, 값3, ... 값N) SELECT CONCAT('concat함수: ',

donghodazzi.tistory.com

 

[SUBSTR & SUBSTRING]

같은 기능을 한다. 문자열의 하위 문자열을 만든다.
=> SUBSTR(str, pos, len) 문자열, 시작 위치값, 가져올 길이 값을 인자로 주고 가져올 수 있다.

아 그리고 뒤에서 부터 읽고 싶다면 시작위치값을 음수로 지정하면된다.

참고: https://needjarvis.tistory.com/64

 

[MySQL] 문자열 추출하기, SUBSTRING, SUBSTR

오라클에도 존재하듯, MySQL에도 SUBSTRING 기능이 존재한다. 이 SUBSTRING은 거의 모든 언어나 DBMS에 자체적으로 내장이 되어 있고, 사용방법도 비슷하다. SUBSTR이라고 써도 되고, SUBSTRING으로 써도 된다

needjarvis.tistory.com

 

[LOWER & LCASE]

LOWER는 문자열을 소문자로 변경한다. (반대는 UPPER) 그런데 LCASE라는 처음보는 함수가 있어서 들고왔다.

둘은 동일한 기능을 수행한다고 한다.

참고: https://www.ibm.com/docs/ko/integration-bus/10.0?topic=functions-lower-lcase

 

LOWER 및 LCASE 함수

 

www.ibm.com

 

자 그러면 이제 문제를 풀어보자. substr로 첫 문자열을 기준으로 분리한다. 이후 각각에 맞는 upper, lower연산을 수행하고, concat으로 합쳐주면 된다.

SELECT user_id, CONCAT(upper(substr(name,1,1)), lower(substr(name,2))) as name
FROM users
order by user_id

 

정렬도 잊지말자.

+ Recent posts