SQL 코드카타 119번
부서별 salary 탑3를 구하고
부서명, 이름, salary를 출력하는 문제. 단, salary가 같을 경우에는 공동 등수를 인정해줘야 한다.
부서별로 나눠서 순위를 매겨야 하고, 여기에 더해 공동 등수까지 인정해줘야 하므로 기본 문법만으로는 해결이 어렵고 window함수를 쓰면 간단히 해결할 수 있다.
SELECT d.NAME AS Department,
a.NAME AS Employee,
salary
FROM (SELECT NAME,
salary,
departmentid,
Dense_rank()
OVER (
partition BY departmentid
ORDER BY salary DESC) AS ranking
FROM employee) a
LEFT JOIN department d
ON a.departmentid = d.id
WHERE ranking <= '3'
먼저 가장 안쪽 인라인뷰 서브쿼리에 dense_rank 함수를 적용한다. 부서별로 랭킹이 각각 매겨져야 하므로 partition by departmentid로 써 주고, 급여가 높은 순서대로 top3를 찾아야 하므로 order by salary desc라고 조건을 적어주면 된다. 그냥 rank()가 아니라 dense_rank()를 쓴 이유는 공동 등수를 인정해줘야 하기 때문. 그냥 rank()를 쓰면 2등이 2명인 경우 다음 차례가 3등이 아니라 4등으로 표시된다.
이제 where조건을 써서 ranking을 3등 이내인 경우만 출력해야 하는데, window함수의 결과물을 where에서 바로 쓸 수는 없다. 따라서 인라인뷰 서브쿼리로 처리하고 부서명도 뽑아와야 하므로 department 테이블과 id를 기준으로 left join해 준다. where절을 써서 ranking의 조건을 적어주고 필요한 컬럼만 호출하면 끝.
이것도 medium난이도 치고는 window함수만 알면 돼서 생각보다 금방 풀렸다. 내 실력이 그만큼 올라온 것이면 더 좋겠고(제발)
숫자로 이루어진 문자열 t와 p가 주어질 때, t에서 p와 길이가 같은 부분문자열 중에서, 이 부분문자열이 나타내는 수가 p가 나타내는 수보다 작거나 같은 것이 나오는 횟수를 return하는 함수 solution을 완성하세요.
예를 들어, t="3141592"이고 p="271" 인 경우, t의 길이가 3인 부분 문자열은 314, 141, 415, 159, 592입니다. 이 문자열이 나타내는 수 중 271보다 작거나 같은 수는 141, 159 2개 입니다.
애증의 알고리즘..
우선 t에서 3자리씩 잘라서 부분 문자열을 만든 후에 리스트에 담아준다.
def solution(t, p):
x = []
for i in range(len(t)):
y = t[i:i+len(p)]
여기까지 입력하고 결과를 출력해보니, p의 자릿수에 해당하는 길이를 가진 것들만 출력되어야 했는데 반복문이 끝까지 다 돌아서 불순물이 섞여나왔다.
def solution(t, p):
x = []
for i in range(len(t)):
if len(t[i:i+len(p)]) == len(p):
x.append(t[i:i+len(p)])
else:
break
조건을 하나 더 추가해서 뽑혀나온 숫자의 길이가 p의 길이와 같을 때에만 x에 해당 값을 추가했고, 아니라면 break를 실행해서 반복문을 끝내게끔 했다.
def solution(t, p):
x = []
count = 0
for i in range(len(t)):
if len(t[i:i+len(p)]) == len(p):
x.append(t[i:i+len(p)])
else:
break
for j in x:
if int(j) <= int(p):
count += 1
return count
이제 다시 x에 담겨있는 요소 j들을 하나씩 꺼내서 if문의 조건을 만족하는지 확인한다. 조건을 만족할 때마다 미리 선언해 둔 count에서 1씩 추가되게끔 만들어주면 끝. 이 때 j와 p 모두 string이므로 비교시에 int를 써서 감싸주어야 한다는 것에만 주의.
오늘 팀플 끝내고 너무 피곤해서 코드카타+TIL 할지말지 잠깐 갈등했다.
그래도 감을 잃지 않기 위해 매일 1문제씩은 꼭 하기로 스스로 룰을 정해두었기 때문에 계획대로 진행했다. 오랫동안 골머리 썩지 않고 무사히 잘 끝마쳐서 배로 뿌듯!🥳