SQL/문제

SQL | Investments in 2016, Department Top Three Salaries, Fix Names in a Table, Delete Duplicate Emails

jjangdoll 2025. 1. 10. 19:21

https://leetcode.com/problems/investments-in-2016/description/


Investments in 2016

내가 쓴 답 (1076ms) :

# 다른 계약자와 동일한 위치에 존재하지 않음 (각자 lat, lon 달라야함)
# tiv_2015 다른 1명 이상과 동일한 가치 가져야함
# tiv_2016 합 소수점 둘째 자리
WITH a AS(
    SELECT	# 위치, tiv_2015 그룹해서 개수 셈
        COUNT(*) OVER (PARTITION BY tiv_2015) AS cnt_tiv_2015,
        COUNT(*) OVER (PARTITION BY lat, lon) AS cnt_lat_lon,
        tiv_2016
    FROM Insurance)
SELECT
    ROUND(SUM(tiv_2016),2) AS tiv_2016
FROM a
WHERE cnt_tiv_2015 != 1 AND cnt_lat_lon = 1

다른 사람이 쓴 답 (433ms) : 

# Write your MySQL query statement below
SELECT ROUND(SUM(tiv_2016), 2) AS tiv_2016
FROM Insurance
WHERE tiv_2015 IN (
    SELECT tiv_2015
    FROM Insurance
    GROUP BY tiv_2015
    HAVING COUNT(*) > 1
)
AND (lat, lon) IN (
    SELECT lat, lon
    FROM Insurance
    GROUP BY lat, lon
    HAVING COUNT(*) = 1
)


https://leetcode.com/problems/department-top-three-salaries/description/


Department Top Three Salaries

내가 쓴 답 (1713ms) : 

# 각 부서 급여 상위 3명 조회
WITH a AS(
    SELECT 
        d.name AS Department,
        e.name AS Employee,
        e.salary AS Salary,
        DENSE_RANK() OVER (PARTITION BY d.name ORDER BY e.salary DESC) AS rnk
    FROM Department d JOIN Employee e ON d.id = e.departmentId)
SELECT
    Department,
    Employee,
    Salary
FROM a
WHERE rnk <= 3 ;

- RANK() : 공동순위가 있으면 (ex. 1등 1명, 2등 2명, 3등 1명) 3등을 건너뛰고 4등으로 

- DENSE_RANK() : RANK와 다르게 공동순위 있어도 순위 안 건너뛰고 3등으로

- ROW_NUMBER() : 정해진 기준에 따라 번호매겨짐

 

📍처음에 ROW_NUMBER() 써서 3명 짜르는 방식으로 했는데 틀렸다고 나옴

📍 그래서 DENSE_RANK()를 사용했는데 이렇게 되면 만약에 1등 2명, 2등 2명인 경우에 4명이 나오는게 아닌가 싶은데 정답 처리가 됨


다른 사람이 쓴 답 (752ms) : 

# Write your MySQL query statement below
SELECT 
    res.Department,
    res.Employee,
    res.salary
FROM (
    SELECT 
        b.name AS Department,
        a.name AS Employee,
        a.salary,
        DENSE_RANK() OVER (
            PARTITION BY a.departmentid 
            ORDER BY a.salary DESC
        ) AS rnk
    FROM employee a 
    JOIN Department b 
    ON  a.departmentid = b.id
) res
WHERE res.rnk <= 3;

- WITH로 안 쓰고 서브쿼리로


https://leetcode.com/problems/fix-names-in-a-table/description/


Fix Names in a Table

내가 쓴 답 (1287ms) : 

# 이름 첫 글자만 대문자, 나머지는 소문자
WITH a AS(
    SELECT 
        user_id,
        UPPER(LEFT(name,1)) AS a,
        LOWER(SUBSTRING(name,2,100)) AS b
    FROM Users)
SELECT
    user_id,
    CONCAT(a,b) AS name
FROM a 
ORDER BY 1;

- 첫 글자 대문자, 나머지 글자 소문자로 만들어준 후 CONCAT으로 합침


다른 사람이 쓴 정답 (523ms) : 

# Write your MySQL query statement below
SELECT user_id, concat(upper(substr(name,1,1)),lower(substr(name,2,length(name)))) AS name
FROM Users
ORDER BY user_id ASC

- 나는 그냥 나머지 글자 처리 할 때 임의로 100이라고 지정했는데 이 사람은 length 활용 

- 굳이 with 안 쓰고 바로 처리 


https://leetcode.com/problems/delete-duplicate-emails/description/


Delete Duplicate Emails

내가 쓴 정답 (3332ms) : 

# id 가장 작은 숫자만 남기고 모든 중복 이메일 삭제
# SELECT 말고 DELETE 사용
DELETE p1
FROM Person p1 JOIN Person p2 ON p1.email = p2.email
WHERE p1.id > p2.id ;

- 셀프 조인 후 아이디 비교 후 아이디 큰 숫자 버림


다른 사람이 쓴 정답 (458ms) : 

delete from person 
where id not in (select t.minid from (select min(id) as minid from person group by email) t)

- not in 이용해서 아이디 최솟값이 아닌 아이디 버림