-
2024-01-24스파르타/TIL(Today I Learned) 2024. 1. 24. 23:15더보기더보기
SQL 코드카타
1321. Restaurant Growth(SQL) (두가지 방식 (서브쿼리 많이 VS 윈도우 함수 많이), WITH, SELECT서브쿼리, WHERE서브쿼리, Datediff, Date_sub interval 6 day, min) (뭔가 어떤 분야에서는 많이 쓰일 듯한 쿼리, 이동평균, 여기선 7일 기준으로 이동평균)
https://leetcode.com/problems/restaurant-growth/description/
해당 날짜를 기준으로 6일전 부터 해당날짜까지 총 amount와 그 평균을 구하는 문제이다.
처음에 또 날짜끼리 그냥 뺏다가 통과못한 한개의 테스트 나와서(그전 tc는 1월내에서 쭉 날짜가 나왔었는데 2월로 넘어가는게 포함된 부분부터 이상하게 작동되었음) DATEDIFF로 수정
WITH day_amount AS( SELECT c.visited_on , SUM(c.amount) amount FROM Customer c GROUP BY c.visited_on ), tot_amount AS ( SELECT da.visited_on, (SELECT SUM(da_s.amount) FROM day_amount da_s WHERE DATEDIFF(da.visited_on, da_s.visited_on) BETWEEN 0 AND 6) amount FROM day_amount da WHERE DATEDIFF(da.visited_on, (SELECT MIN(da_s2.visited_on) FROM day_amount da_s2))>=6 ) SELECT ta.visited_on, ta.amount, ROUND((ta.amount)/7,2) average_amount FROM tot_amount ta
서브쿼리를 다소 많이 썼기에 느릴수도 있다고 생각되어(제일 첫 제출 시에는 런타임이 986ms, beats11.11%로 늦은 축에 속해있었다) 다른 나보다 빠른 런타임이 나온 사람들의 쿼리를 보니 방식은 조금씩 다르지만 서브쿼리 쓴 갯수도 크게 차이나지 않고 어떤 사람은 윈도우 함수까지 사용하였는데 나보다 빨리 나왔길래 그냥 다시 제출을 해보니(이번에는 제출 후 바로 제출이 아닌 많은 시간을 텀을 주고 다시 제출하였다) 540ms에 99.15%로 상위권으로 나와서 다른 사람들이 solution으로 제출한 것에서는 어떻게 했는지만 살펴보고 넘어갈려고 한다. (살펴봤지만 획기적으로 성능을 올릴만한 요소는 보이지 않는 듯하다)
아래는 다른사람 들의 쿼리들이다
# Write your MySQL query statement below SELECT c1.visited_on, ( SELECT SUM(c2.amount) FROM Customer c2 WHERE c2.visited_on BETWEEN DATE_SUB(c1.visited_on, INTERVAL 6 DAY) AND c1.visited_on ) AS amount, ROUND( ( SELECT SUM(c2.amount) / 7 FROM Customer c2 WHERE c2.visited_on BETWEEN DATE_SUB(c1.visited_on, INTERVAL 6 DAY) AND c1.visited_on ), 2 ) AS average_amount FROM (SELECT DISTINCT visited_on FROM Customer) c1 WHERE c1.visited_on >= (SELECT DATE_ADD(MIN(visited_on), INTERVAL 6 DAY) FROM Customer) ORDER BY c1.visited_on ASC;
# Write your MySQL query statement below SELECT visited_on, ( SELECT SUM(amount) FROM customer WHERE visited_on BETWEEN DATE_SUB(c.visited_on, INTERVAL 6 DAY) AND c.visited_on ) AS amount, ROUND( ( SELECT SUM(amount) / 7 FROM customer WHERE visited_on BETWEEN DATE_SUB(c.visited_on, INTERVAL 6 DAY) AND c.visited_on ), 2 ) AS average_amount FROM customer c WHERE visited_on >= ( SELECT DATE_ADD(MIN(visited_on), INTERVAL 6 DAY) FROM customer ) GROUP BY visited_on;
# Write your MySQL query statement below SELECT visited_on, amount, ROUND(amount/7, 2) average_amount FROM ( SELECT DISTINCT visited_on, SUM(amount) OVER(ORDER BY visited_on RANGE BETWEEN INTERVAL 6 DAY PRECEDING AND CURRENT ROW) amount, MIN(visited_on) OVER() 1st_date FROM Customer ) t WHERE visited_on>= 1st_date+6;
이 방식은 윈도우 함수를 좀 사용하긴 했지만 색다른 듯 싶어서(쿼리도 간단명료하고) 참고할만 할듯하다 그런데 성능은 잘모르겠다 질문할려고 했는데 깜박하고 넘어가버려서 다음에 질문을 할 듯하다.
# Write your MySQL query statement below WITH cte AS ( SELECT visited_on , SUM(amount) amount FROM Customer GROUP BY visited_on ), cte1 AS ( SELECT visited_on , SUM(amount) OVER(ORDER BY visited_on ROWS BETWEEN 6 preceding and CURRENT ROW) amount , ROUND(AVG(amount) OVER(ORDER BY visited_on ROWS BETWEEN 6 preceding and CURRENT ROW),2) average_amount , ROW_NUMBER()OVER(ORDER BY visited_on) RN FROM cte ) SELECT visited_on , amount , average_amount FROM cte1 WHERE RN > 6 ORDER BY visited_on
ROWS과 preceding, current row 이라는 처음 보는 함수? 들을 사용했길래 궁금해서 찾아보았는데
대강 해당하는 row들의 범위들을 정해주는 것인데 ROWS 행들 그런데 범위를 현재 행 기준으로 6개이전 행부터 지금 행까지로 한정 지어주는 방식인듯 하다.
602. Friend Requests II: Who Has the Most Friends(SQL) (with, union(union all과 비교), select서브쿼리, order + LIMIT, 임시 테이블 없이 바로 서브쿼리 하나로 똭! union all 방식이 의도해서 전부 세기엔 좋은듯)
https://leetcode.com/problems/friend-requests-ii-who-has-the-most-friends/description/
각 친구 신청에 대해 요청자와 수락자에 대한 정보를 보고 친구가 가장 많은 id와 그 id의 친구 수를 출력하는 문제이다
처음에 중복을 제거해주기 위해 바로 union을 썼지만 그 후 비교 테스트를 위해 union all도 같이 해주었는데 서순상 union all을 먼저 적고 union을 쓰면 이렇게 달라진다 말하는게 나을 듯하여 그렇게 적도록 하겠다
WITH id_list AS ( SELECT r1.requester_id id FROM RequestAccepted r1 UNION ALL SELECT r2.accepter_id id FROM RequestAccepted r2 ) SELECT * FROM id_list il #out | id | | -- | | 1 | | 1 | | 2 | | 3 | | 2 | | 3 | | 3 | | 4 |
WITH id_list AS ( SELECT r1.requester_id id FROM RequestAccepted r1 UNION SELECT r2.accepter_id id FROM RequestAccepted r2 ) SELECT * FROM id_list il #out | id | | -- | | 1 | | 2 | | 3 | | 4 |
union은 전에 말했듯이 중복을 제거하는 distinct 기능도 포함하고 있어서 알아서 자동으로 중복을 제외하고 나오게 된다
WITH id_list AS ( SELECT r1.requester_id id FROM RequestAccepted r1 UNION SELECT r2.accepter_id id FROM RequestAccepted r2 ) SELECT il.id, (SELECT COUNT(r1_s.requester_id) FROM RequestAccepted r1_s WHERE r1_s.requester_id = il.id) + (SELECT COUNT(r2_s.accepter_id) FROM RequestAccepted r2_s WHERE r2_s.accepter_id = il.id) num FROM id_list il ORDER BY num DESC LIMIT 1
그 뒤 쿼리에 대해 간단히 설명하면 우선 친구 요청한 id와 친구 신청한 id를 전부 가져와서 중복을 제거하고 하나의 열로 합쳐준다 그 뒤 그 테이블을 가져와 그 아이디에 대하여 각 id에 해당하는 요청한 수 와 요청받은 수를 세어서 합쳐준다 그 뒤 num의 크기대로 내림차순 정렬을 하고 가장 위의 1개만을 출력한다.
그 외 아래는 다른사람들의 쿼리이다.
select id, count(*) as num from ( select requester_id as id from RequestAccepted union all select accepter_id as id from RequestAccepted )t group by 1 order by count(*) desc limit 1
서브 쿼리를 두개 쓰지 않고 한개만 써서 직관적으로 하는 방식
따로 세어줄 필요 없이 그냥 union all을 이용하여 전부 가져온 뒤 전체로 id별로 그룹지어 쭉 세어준다
# Write your MySQL query statement below WITH FriendsCount AS ( SELECT requester_id AS id, COUNT(requester_id) AS num FROM RequestAccepted GROUP BY requester_id UNION ALL SELECT accepter_id AS id, COUNT(accepter_id) AS num FROM RequestAccepted GROUP BY accepter_id ) SELECT id, SUM(num) AS num FROM FriendsCount -- WHERE num = (SELECT MAX(num) FROM temp); GROUP BY id ORDER BY num DESC LIMIT 1;
서브쿼리를 아예 쓰지 않고 각자 세어주고 합쳐준 상황
그러고 보니 임시테이블 한번 만드는 과정은 서브쿼리 한번써주는 것과 동일한 연산을 요구한다고 생각하면 될지 궁금해서 질문을 드렸는데 관련해서는 아래에서 질문부분에서 다시 얘기하도록 하겠다
585. Investments in 2016(SQL) (EXISTS와 NOT EXISTS 동시에 사용, where IN 서브쿼리, except, intersect, 성능비교 하는법 알고 싶음 , not(조건)형식)
https://leetcode.com/problems/investments-in-2016/
좌표는 서로 다른데 tiv_2015의 값이 같은 다른 pid가 있는 pid의 tiv_2016의 총합을 구하는 문제이다.
SELECT i.pid #ROUND(SUM(i.tiv_2016),2) tiv_2016 FROM Insurance i WHERE EXISTS ( SELECT i2.pid FROM Insurance i2 WHERE i2.pid != i.pid AND i2.tiv_2015 =i.tiv_2015 AND (i2.lat != i.lat OR i2.lon != i.lon) )
#입력 | pid | tiv_2015 | tiv_2016 | lat | lon | | --- | -------- | -------- | --- | --- | | 1 | 10 | 5 | 10 | 10 | | 2 | 20 | 20 | 20 | 20 | | 3 | 10 | 30 | 20 | 20 | | 4 | 10 | 40 | 40 | 40 | #이렇게 나옴 | pid | | --- | | 1 | | 3 | | 4 | #원래는 1 4만 나와야함
이렇게하면 tiv_2015값 같은게 존재하는데 다른 데 좌표 같은게 있어도 값같고 좌표 둘중 하나라도 다른게 있으면 EXISTS안에 행 존재해버리기 때문에
SELECT i.pid #ROUND(SUM(i.tiv_2016),2) tiv_2016 FROM Insurance i WHERE EXISTS ( SELECT i2.pid FROM Insurance i2 WHERE i2.pid != i.pid AND i2.tiv_2015 =i.tiv_2015 INTERSECT SELECT i3.pid FROM Insurance i3 WHERE i3.pid != i.pid AND NOT (i3.lat = i.lat AND i3.lon = i.lon) )
이렇게도 되야할 것 같은데 왜 여전히 1 3 4가 나오지?
SELECT i.pid #ROUND(SUM(i.tiv_2016),2) tiv_2016 FROM Insurance i WHERE EXISTS ( SELECT i2.pid FROM Insurance i2 WHERE i2.pid != i.pid AND i2.tiv_2015 =i.tiv_2015 EXCEPT SELECT i3.pid FROM Insurance i3 WHERE i3.pid != i.pid AND (i3.lat = i.lat AND i3.lon = i.lon) )
이건 진짜 왜???
아 값 같은얘랑 좌표 같은얘랑 같은 얘가 아니면 의미가 없겠구나 i3로 해준 서브쿼리는
지금 우리는 i3로 나오는 결과가 없는 얘들이여야하니 있으면 안됨
EXISTS 두 개도 가능한가 해서 해봤는데 무사히 됐음
SELECT ROUND(SUM(i.tiv_2016),2) tiv_2016 FROM Insurance i WHERE EXISTS ( SELECT i2.pid FROM Insurance i2 WHERE i2.pid != i.pid AND i2.tiv_2015 =i.tiv_2015 ) AND NOT EXISTS( SELECT i3.pid FROM Insurance i3 WHERE i3.pid != i.pid AND (i3.lat = i.lat AND i3.lon = i.lon) )
첫 제출 시 1839ms 5.01%가 나와 거의 최하위로 나왔는데 EXISTS쓰는 과정에서 연산이 오래 걸린 것인가 하는 느낌이 들었다
우선 쿼리를 간단히 설명하면 우선 Insurance테이블에서 가져오는데 ROUND(SUM(i.tiv_2016),2) 을 통해서 tiv_2016의 총합을 구하고 반올림하여 둘째자리까지 표시하도록 한 뒤 tiv_2016로 컬럼을 표시한다 단 이 때 pid가 서로 다른데 tiv_2015가 같은 것이 있고, pid가 서로 다른데 좌표가 같은 것이 없는 경우에 대해서만 출력해준다.
다른 사람들은 아래와 같이 거의 대부분이 where in을 이용해서 하였다
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 )
WHERE 안에 in으로 해서 sub쿼리 두 개를 사용하여 안에 포함되는 녀석들로만 해주는 방식이라 설명가능할 듯 하다
솔직히 리트코드상으로 제출한 것으로는 역시 데이터가 그리 크지 않아서 그런지 성능차가 그리 커보이지는 않았다
더보기더보기질문한 내용
우선 Leetcod runtime beats 관련해서 성능 확인하는 것에 대해 질문을 드렸다
하지만 내가 체감했듯이 단순 쿼리의 성능 뿐 아니라 서버나 인터넷 등 다른 외부적인 영향에 크게 받는 듯하기도하고 제출하고 바로 다시 제출하면 빠르게 되는 등 이것을 신용할 수 없는 것 같은데 맞는지 여쭤보고 또 그러면 성능 확인을 할려하니 어떻게 하면 좋을지에 대해 여쭤보았는데
튜터님이 맞다고 하셨고, 또 리트코트로는 제출했을 때 성능을 바로 확인하기는 힘들 것이라고 하셨다 클라우드 환경으로 하면 바로바로 나와서 가능하겠지만 그렇게 하기는 힘들 것 같다고 생각하셨고, 그래서 리트코트는 성능이 어차피 테스트 코드 수준으로는 데이터 양이 별로 안커서 성능이 차이가 별로 안난다고 하셨으며, 그냥 문제를 해결하는데 집중하고 해결했으면 다른 사람은 어떻게 했나 살펴보는 정도만 하면 충분할 것 같다고 말씀해주셨다
(그리고 추가로 윈도우 함수 관련하여 성능에 좋게 작용할 수도 있는지도 물어볼려했는데 통채로 생각하고 넘어가버려서 깜박하고 질문을 못드렸다)
그리고 join이나 서브쿼리같은 부분에서 연결해줄때 테이블명.컬럼명 = 테이블명.컬럼명 부분에서 한쪽 테이블명을 생략해도 되는지 여쭤봤는데 (내가 봤던 부분은 리트코트에서 주로 서브쿼리쪽은 그냥 바로 컬럼만 적는 경우를 많이 봤으며, 메인쿼리쪽 테이블명을 생략하는 경우도 본적이 있었던 것 같다) 우선 작동 자체는 별 문제 없이 될 수 있다 하지만 복잡하고 긴 쿼리에서 저렇게 써버리면 못 알아봐서 다른사람들에게 안좋은 소리를 들을 수도 있으니 가능한 적는게 무조건 좋다고 생각한다고 말씀하셨다.
또 추가로 관련지어서 저런 식으로 테이블명 안붙이는게 성능에 관련이 있는지 여쭤봤는데 아마 생각하시기로는 거의 영향 없다고 보는게 맞을 것 같다고 말씀해주셨다 그러니 무조건 붙여서 쓰는 것을 습관으로 계속 이어가는 것이 좋을 것 같다.
그리고 추가로 ESCAPE를 쓸때 #말고 다른 기호를 사용할 수도 있는지 여쭤봤는데 일단 docs등을 살펴보았을 때는 꼭 #만을 쓸 수 있다는 말을 보지 못하시긴 하였지만, 흔히 말하는 국룰로 암묵적인 표준? 통일? 약속 같은 것이라 생각하면 되는 것 같다 진짜 #말고 다른 것을 쓰는 경우를 보지 못하였고, 또 협업등에서 다른 사람들이 내 쿼리를 가능한 쉽게 이해할 수 있게 해야하기 때문에 통일해서 #을 쓰는 것은 중요할 것이라고 다시 한번 더 말씀해주셨다(물론 나도 대부분 쓰는 것을 맞춰서 쓰는 것이 중요하다 생각하고 그렇게 할 예정이였지만 그래도 그냥 호기심에 다른 것도 가능은 한지 여쭤본 것이였다!)
그리고 with구문 관련해서 여쭤보았는데 with 테이블 As() 쓰고 줄바꿈해서 띄워써도 되는지 다시한번더 확인차 여쭤보았는데 가능하다고 하셨고 옛날에 내가 겪었던 with구문에서 띄워서 썼을 때 에러가 난 것은 아마 with와 띄워써서가 아닌 select랑 from부분 사이에 띄어써서 에러가 떴을 것으로 예상된다
또 추가로 wtih의 유효한 범위는 어디까지 인지 여쭤봤는데 역시 내가 예상한 대로 메인 쿼리 부분이 마치는 지점 (;로)까지 유효하며 임시이기 때문에 쿼리가 끝나면 사라진다고 생각하면 된다고 하셨다 만약 쿼리 끝나고도 계속 쓰고 싶다면 view로 생성해서 밖으로 끄집어 내야한다고도 말씀해주셨다.
그리고 추가로 with를 통해 임시 테이블 한번 해주는게 서브쿼리 한번 한 것과 연산하는 양 자체가 같다고 생각하면 될지 물어봤는데 예상과 달리 조금 복잡한 답변이 돌아왔다 서브쿼리 경우 값을 간단히 빼와서 넣을 때는 더 빠를 듯하며, 테이블 만들어서 값을 계속 빼와야하는 경우는 테이블이 빠를 것 같다고하셨으며, 추가로 DB에 따라 달라질수있다고 하셨다 그래서 이부분은 내가 추가적으로 더 써보면서 체감을 해봐야 터득이 될 것 같았다 그리고 내가 변하지 않는 with의 목적이자 효과가 임시테이블 역할으로 가독성 높이기 위해 테이블을 변수처럼 추가로 쓰는 것이라 생각하면 될지 확인차 여쭤봤는데 그렇다고 하셨다 이 점은 변하지 않는 with의 목적이 맞다고 하셨다.
그리고 Cross join을 했더니 가져오는 테이블의 순서가 뒤집힌채로 붙여졌던 적이 있어 원래 cross join이 이런 결과를 가져오는 것인지 여쭤봤는데 그렇지 않다며 왜그렇게 나온지는 모르겠다고 결론이 내렸다. 왜냐하면 튜터님이 테스트 해보시길 다른 mysql환경에서 했을 때도 정렬된채로 멀쩡하게 나왔고 리트코트의 포스트그리SQL에서는 멀쩡하게 나왔는데 리트코트 mysql에서 할 경우만 이상한 결과가 나왔으므로 아마 리트코트에서 mysql 실행시켜주는 과정에서 저러한 결과가 나타난 듯 했지만 더 깊게 원인을 파악하기도 어렵고 굳이 그럴 중요성은 없다고 판단했기 때문이다.
그리고 0으로 나누기 하면 null로 나오게 되어있는지 여쭤봤는데 mysql 버전이 7이하면 null로 나온다고 하며 원래는 Error가 나와야 정상이라고 하셨다(이점은 튜터님도 검색해보시고는 처음 아셨다면서 신기해하셨다)
그리고 그룹지어준 테이블에 대해 Max(COUNT(컬럼))로 바로 최대값을 구할 수없다는 사실은 문법이 그런 것이라 알겠지만 이유가 잘 이해가 안되는데 혹시 쉽게 납득갈만한 이해방식이 있을지 여쭤보았는데 튜터님이 당연하다고 생각되시는 부분이라 어쩔 수 없이 그냥 문법이 그러니 최대값을 구할 때는 다른 방식으로 구해야한다고 말씀하셨다
그리고 sum(조건)과 같은 방식으로 쓰는 것이 가능한지 여쭤봤는데 튜터님도 처음 보는 방식이라고 신기해 하시면서 검색하시면서 확인해보신 결과 (참,거짓 판별하여 0, 1로 리턴되어 그에 따라 출력하는?) mysql에서만 가능한 방식으로 그리고 간단한 상황이 아니라면 where같은 게 있는 조금 복잡해지는 쿼리일 경우 필터링하는 과정 등에 의해서 연산이 오히려 그냥 바로 where등으로 따로 필터링해줬을 때보다 연산이 느려질 것으로 예상된다고 하셨다(왠만한 상황에서는 이런 방식으로 안쓰고, 문제의 쿼리 예시처럼 엄청 간단한 경우에만 가독성 좋게 간단히 쓸때정도만 쓸 수 있을 듯하다)
그리고 where등 조건에서 not(조건) 같은 방식으로 쓰는게 써도 괜찮은 방식인지 여쭤봤는데
일단 그런 방식으로는 복잡해져서 알아보기 힘들듯해 쓰지 않을 것 같다고 말씀하셨다. 내가 사용한 예시의 경우 다른 조건 AND NOT(조건) 이런 식으로 되어있었는데 가독성 상으로 ()안이 참인데 이게 not으로 거짓으로 바꾸고 이런식으로 생각하는 것도 너무 복잡해질 것 같다고 말씀하셨고, 또 연산자들 사이에서 AND가 NOT보다 먼저 하는 것으로 알고 있어 AND먼저하고 그다음 NOT으로 하다보면 생각과 다른 결과가 나올 수 있어 이런 방식은 안쓰는게 좋겠다고 말씀하셨다
추가로 전에 쿼리의 실행 순서 FROM - WHERE ... 에서 예외적으로 다를 경우가 있을 수 있다고 하셨는데 EXISTS가 그 예에 해당할지 여쭤보니 맞다고 하셨으며 그런 식으로 가끔 다르게 실행순서를 가지는 녀석들이 있다고 하셨다
추가로 EXIST에 대해서는 튜터님도 많이 안 쓰셨는 듯 했으며 IN은 다들 많이 쓰는데 EXIST는 잘 안쓰는 듯한 반응이셨는데 제가 IN과 EXISTS 둘다 쓸 수 있는 상황에서는 EXISTS를 사용하는 것이 유리할 것으로 이해했다고 말씀드리니 조금 찾아보시고 바로 제가 이해한대로 이해하고 계시면 될 것같다고 말씀해주셨다(EXISTS와 NOT EXISTS둘다 쓰는 방식을 써도 될지도 같이 여쭤본 것이였는데 위와 같은 답변과 함께 말씀하셨기에 이 방식은 써도 된다는 의미로 받아드렸다)
그리고 리트코트에서는 어떻게든 코드를 짧게 쓰는 사람들이 보여 가독성이 나빠지는 대신 미묘하게라도 성능이 좋아지는지 여쭤봤는데 전혀! 아니라고 하셨다 옛날이야 메모리가 작아 하나하나가 소중해서 그랬을 수도 있으나 이제는 단위가 훨씬 크게 가지고 있기에 진짜 극한의 상황이면 모를까 일반적인 상황에서는 티도 안날정도 차이가 난다면 날 것이라고 하셨고, 가독성 좋게 띄워쓰고 하는 것이 좋다고 추천하셨다
그리고 추가로 과제해설에서 해주신 들여쓰기하시는 방식 보통 하는 방식인지 여쭤봤는데 일단 튜터님과 튜터님 팀은 그런 방식으로 들여쓰기 하시는 것을 약속으로하여 사용하고 있다고 하셨다(이유로는 튜터님이 딱딱 SELECT, FROM 등이 같은 줄이 있는게 딱 보기 편하며, 줄이 길어져서 옆으로 슬라이드를 옮기는 일을 엄청 싫어하시다 보니 그런 방식이 자리 잡으셨다고 하셨다) 우선 다른 사람들도 그렇게 하는게 보통일지 여쭤보았으나 어디까지나 쿼리를 작성하는 들여쓰기 방식은 자유이긴 하다고 말씀하셨다(하지만 나도 튜터님과 비슷한 생각이기에 튜터님이 쓰는 방식을 최대한 따라해볼려고 한다) 추가로 이렇게 들여쓰기 해두면 욕먹을 일 없이 SQL 좀한다는 인상을 받을 수 있을 것이라고 추천도 해주셨다
그리고 mysql에서 행과 열을 통째로 엑셀 처럼 바꾸는 방식이 없냐고 여쭤보니 없다고 하셨으며 할려면 복잡한 과정으로 일일히 옮겨야하는데 그러느니 차라리 새로 따로 전처리해서 만드는게 빠를 것 같다고 말씀하셨으며, 행으로 추가하는 것은 비교적 간단하지만 열로 값을 추가하는 경우는 하기 좀 힘들다고 하셨는데, 이는 데이터베이스이기 때문에 그렇다고 하셨으며, 데이터베이스라 락킹이 되어있다고 그러셨다
그리고 관련지어 컬럼 한번에 추가하는 방식이 없냐 여쭤봤는데 하기 힘들다 하셨으며, 잘 안쓰기는 한데 SQL에서도 for문처럼 반복을 할 수 있다고 하셨으며, DBEAVER에서는 해본적이 없어서 모르시니 확인해봐 달라고 하셨는데 sql CLI 즉 SQL을 터미널에서 조작할때 잘 사용은 하지 않지만 스크립트로 for문 처럼 반복작업을 수행해줄 수 있다고 하셨다.
그리고 현재 사용중인 데이터 베이스가 어떤 것인지 확인하는 방법이 있는지도 여쭤봤는데 mysql의 경우 없는 듯하다고 하셨으며, 포스트그레이스SQL은 있다고 하시며 포스트그레이스가 (여러 점으로 봐서)진짜 잘 만든 것 같다고 느껴진다고 덧붙여 말씀해주셨다
그리고 순서상으로는 가장 먼저 질문 드렸던 부분인 SQL이 가지는 pandas 에 비교해 장점이 무엇인지 여쭤봤는데 데이터베이스에서 바로 조작이 가능하다는 점이 유일한 장점이라고 말씀하셨다 pandas의 경우 직접 데이터를 메모리로 가져와서 처리해야하기 때문에 데이터가 클경우 시간이 전처리하는데만 해도 1시간 넘게 걸릴 수도 있는데 SQL의 경우 데이터베이스에서 바로 쿼리를 통해 필요한 부분만 잘라서 바로 전처리가 가능하기에 그점이 유일한 장점이자 쓰는 이유라고 하셨다 여담으로 보통 간단한 것은 그냥 SQL에서 데이터를 추출하여 파이썬에서 판다스로 전처리를 다 해주고 SQL식으로 처리해준다음에 다시 데이터베이스로 넘기는 방식을 다들 자주 사용한다고 하셨다.
그리고 마지막으로 ADsP자격증 관련하여 슬랙에서 말이 나와 여쭤보았는데 따로 적어두지도 않았고 말내용이 조금 길기도 했으며, 각자 스스로 판단해야할 부분이라 조금 애매하게 적을 듯한데, 우선 좀 분석 잘한다 싶은 사람들은 다들 가지고 있는 자격증이라 안 가지고 있는 사람이 오히려 더 찾기 힘들 정도이며, 앞으로 커리큘럼동안 배운 내용들이 자격증 시험에 대다수 나올 것이기 때문에 열심히 하면 할만하다고 느껴져서 바로 시험을 접수신청하였다.
오늘은 코트카타 간단히 하고 시각화 강의 부분 마저 다듣고, 과제 나온것 전처리부분까지만 간단히 해보고, 그뒤로는 질문하고 정리하는데 시간을 다 할애하였다 과제 관련해서와 통계부분에 대해 복습을 못해준 것이 아쉽긴 하지만 질문시간에 이런저런 조언을 많이 받았기 때문에 충분히 가치있는 시간이였다고 생각된다.(그리고 처음에 혹여나 하시는 우려로 너무 SQL만 깊이 잡고 있어 다른 공부를 제대로 못하는 건 아닐지 걱정하셨는데 (사실 빨리 일정수준이상으로 졸업하고 꾸준히 감만 유지하는 느낌으로 다른 새로운 것을 배우고 싶어서 괜한 걱정이라고 생각되긴 했다) 그러면서 다른 내용들도 충분히 집중해서 공부해줘야하는데 어디까지나 커리큘럼에서 알려주는 내용은 다 기초이기에 추가로 심화적인 내용을 공부하기를 추천드린다고 하셨다 예를 들어 파이썬의 경우 데이터 분석가로써 파이썬 공부 관련해 검색해보면 나오니 참고해서 공부하면 좋다고 하셨고 (여러 용어 알려주시면서 얘기해주셨지만 내가 아직 안 익숙한 단어들이라 잘 못알아듣고 못적었다..ㅠ 그래도 이래저래 많이 보이던 단어들 인 것은 알고 있어서 그것들을 통해 확인할 수 있을 듯하다) 그리고 나중에 여유가 되면 미국의 추세, 유행이 보통 2년정도 뒤 한국에서도 추세가 되고 유행적으로 많이 쓰인다고 하시면서 판다스를 개선해서 하기 위해 만든 다스크라는 것과 폴라라는 것도 공부해두면 나중에 엄청난 강점으로 작용할 수 있을 것이라 하시면서 추천해주셨다)
그리고 내일 있을 상담을 위해서 아직 남은 준비사항들을 완수해야하기에 오늘은 여기서 마무리 짓고 준비를 마저하러 가보도록 하겠다
'스파르타 > TIL(Today I Learned)' 카테고리의 다른 글
2024-01-26 (1) 2024.01.26 2024-01-25 (1) 2024.01.26 2024-01-23 (1) 2024.01.23 2024-01-22 (1) 2024.01.22 2024-01-20~2024-01-21 (1) 2024.01.22