금일 SQL 공부를 시작한 지 3번째이다. 꾸준히 잊지 않고 복습하면서 진도를 나아가보면 새로운 명령어를 배우고 효율적인 명령어로 바꾸거나 지식을 습득하여서 군대에서 목표 자격증 SQLD에도 도움이 될 것이고 추후 효율성을 기반한 고급 SQL 개발자로서 발전하는데 초목이라 생각된다.
Table: Users
+----------------+---------+
| Column Name | Type |
+----------------+---------+
| user_id | int |
| name | varchar |
+----------------+---------+
user_id is the primary key for this table.
This table contains the ID and the name of the user. The name consists of only lowercase and uppercase characters.
Write an SQL query 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.
The query result format is in the following example.
Example 1:
Input:
Users table:
+---------+-------+
| user_id | name |
+---------+-------+
| 1 | aLice |
| 2 | bOB |
+---------+-------+
Output:
+---------+-------+
| user_id | name |
+---------+-------+
| 1 | Alice |
| 2 | Bob |
+---------+-------+
이 문제는 맨 처음문자만 대문자 나머지는 소문자로 만들어 출력하는 문제이다.
mysql 과 Oracle 두가지 버전이 있다.
mysql : SELECT user_id,concat(upper(substr(name,1,1)),lower(substr(name,2,length(name)))) as 'name'
FROM Users ORDER BY user_id;
여기서 우선 concat 명령어로 두가지 값을 합칠 것이고 substr 명령어를 통해 name 데이터에서 첫 번째 값부터 뒤에 지정한 첫 번째 길이 즉 첫 번째 값만 잘라서 Upper 명령어로 대문자로 변경한다.
또한 뒤에서는 substr에서 name 데이터에서 2번째 위치부터 현재 데이터 길이 까지 잘라서 lower 명령어로 소문자로 만든 뒤 concat 명령어를 통해 합친다.
Oracle 버전 : select user_id, initcap(name) name from Users order by user_id; Oracle 버전은 initcap 이라는 명령어가 위에서 적은 Mysql 명령어 기능을 한번에수행한다.
initcap 명령어를 처음 알았고 각 제공하는 DBMS에서 차이가 있는점을 상기 해야한다.
Table Activities:
+-------------+---------+
| Column Name | Type |
+-------------+---------+
| sell_date | date |
| product | varchar |
+-------------+---------+
There is no primary key for this table, it may contain duplicates.
Each row of this table contains the product name and the date it was sold in a market.
Write an SQL query to find for each date the number of different products sold and their names.
The sold products names for each date should be sorted lexicographically.
Return the result table ordered by sell_date.
The query result format is in the following example.
Example 1:
Input:
Activities table:
+------------+------------+
| sell_date | product |
+------------+------------+
| 2020-05-30 | Headphone |
| 2020-06-01 | Pencil |
| 2020-06-02 | Mask |
| 2020-05-30 | Basketball |
| 2020-06-01 | Bible |
| 2020-06-02 | Mask |
| 2020-05-30 | T-Shirt |
+------------+------------+
Output:
+------------+----------+------------------------------+
| sell_date | num_sold | products |
+------------+----------+------------------------------+
| 2020-05-30 | 3 | Basketball,Headphone,T-shirt |
| 2020-06-01 | 2 | Bible,Pencil |
| 2020-06-02 | 1 | Mask |
+------------+----------+------------------------------+
Explanation:
For 2020-05-30, Sold items were (Headphone, Basketball, T-shirt), we sort them lexicographically and separate them by a comma.
For 2020-06-01, Sold items were (Pencil, Bible), we sort them lexicographically and separate them by a comma.
For 2020-06-02, the Sold item is (Mask), we just return it.
이 문제는 각 팔린날 제품을 한번에 출력시켜야한다.
처음 필자는
select sell_date,count(distinct product) as 'num_sold', product as 'products' from Activities group by sell_date order by sell_date;
로 작성하였다. 여기서 문제점은 products 속성에서 맨 앞 데이터만 출력한다는 점이다. 따라서 이 문제를 해결하고자 구글링, 자료를 찾아보았다. 기존 지식으로는 해결하기 힘들다는 판단이 들었다.
그 중 group_concat 명령어가 있었다. 이 명령어는 원하는 속성에 대한 한줄로 표현한다.
select sell_date,count(distinct product) as 'num_sold', group_concat(distinct product) as 'products' from Activities group by sell_date order by sell_date;
로 작성하여 해결하였다.
이번 문제에서는 group_concat 이라는 명령어를 알게되었다. 이 명령어는 효율적이고 자주 쓰일거라 생각되므로 복습을 하고 상기하여 완벽하게 이해 해야 한다.
group_concat 에서 나온 데이터들은 ','로 구분되어서 나온다. 만약 구분 방법을 바꾸고 싶으면 SEPARATOR <- 를 추가하고자 한다 group_concat(name SEPARATOR '-') , group_concat(name SEPARATOR '\')
Table: Patients
+--------------+---------+
| Column Name | Type |
+--------------+---------+
| patient_id | int |
| patient_name | varchar |
| conditions | varchar |
+--------------+---------+
patient_id is the primary key for this table.
'conditions' contains 0 or more code separated by spaces.
This table contains information of the patients in the hospital.
Write an SQL query to report the patient_id, patient_name all conditions of patients who have Type I Diabetes. Type I Diabetes always starts with DIAB1 prefix
Return the result table in any order.
The query result format is in the following example.
Example 1:
Input:
Patients table:
+------------+--------------+--------------+
| patient_id | patient_name | conditions |
+------------+--------------+--------------+
| 1 | Daniel | YFEV COUGH |
| 2 | Alice | |
| 3 | Bob | DIAB100 MYOP |
| 4 | George | ACNE DIAB100 |
| 5 | Alain | DIAB201 |
+------------+--------------+--------------+
Output:
+------------+--------------+--------------+
| patient_id | patient_name | conditions |
+------------+--------------+--------------+
| 3 | Bob | DIAB100 MYOP |
| 4 | George | ACNE DIAB100 |
+------------+--------------+--------------+
Explanation: Bob and George both have a condition that starts with DIAB1.
이 문제는 I형 백혈구가 있는 데이터를 출력하는 것이다. I형 백혈구는 DIAB1 이 접두사로 있다한다. 이점을 유의하여 풀어보게 된다면
SELECT patient_id, patient_name, conditions FROM Patients Where conditions like 'DIAB1%' or conditions like '% DIAB1%'
로 풀 수 있다. DIAB1 접두사로 시작하거나 끝나는 문을 구현시키면 가능하다.
또한 이 문제를 풀게 되면서
REGEXP
명령어를 알게 되었다. 이 명령어는 정규표현식을 통해서도 구현 가능하다.
select * from patients where conditions regexp '\\bDIAB1'
로 구현할 수 있다.
이 쿼리는 위와 같은 기능을 하며 처음 필자는 \bDIAB1 로 작성하였다.
\b - 단어의 경계 확인(space bar)
이기 떄문이다 하지만 LeetCode에서는 에러가 뜨므로 \를 하나 더추가하여 mysql에서 특수문자로 인식하게 하였다.또는 더 쉽게 select * from patients where conditions regexp '^DIAB1| DIAB1' 로 도 가능하다(뒷 부분 DIAB1 에 앞에는 공백이 있습니다)
금일 3문제를 풀면서 새롭게 알게 된 명령어가 많다 Oracle 에서 Initcap, Group_concat , Regexp 중에서Regexp 명령어는 정규표현식으로 표현하므로 아직 미숙한 점이 있지만 오늘 새로운 지식을 배우면서 복습을 하면서 완벽히 이해하고 추후 다른 문제에서 활용하여 메모리를 적게 ,실행속도는 빠르게 할 수 있는 효율적인 쿼리문에 도움이 될거라 생각된다.
'군대 활동 > 공부' 카테고리의 다른 글
알고리즘 공부 Leetcode Day6 (0) | 2022.10.13 |
---|---|
SQL 공부 (leetcode 4편) (0) | 2022.10.13 |
알고리즘 공부 Leetcode Day5 (0) | 2022.10.09 |
SQL 공부 (leetcode 2편) (0) | 2022.10.07 |
알고리즘 공부 Leetcode Day4 (0) | 2022.10.06 |