[2025.10.29] 오늘의 학습 키워드 - 리마인드

허진원·2025년 10월 29일

내일배움캠프 TIL

목록 보기
8/41
  1. 오늘 학습 키워드
  • python 선행학습(?) 하기
  • 이번 주차에 배웠던 내용들 되짚어보며 리마인드 하기
  1. 오늘 학습한 내용을 나만의 언어로 정리하기
    다음 주부터 SQL 뿐만 아니라 python 학습도 병행하게 된다. 이에 앞서 기본적인 개념들만 간단하게 확인하고자 내일배움캠프에서 지급해주는 python 강의 영상을 시청했다.

    무슨 일을 하든지, 기본이 가장 중요하다. 그런 의미로 이번 주차에 학습했던 내용들을 상기시키며 내가 올바르게 이해한 것이 맞는지 다시 한 번 확인하는 의미로 어제까지 배웠던 내용들을 리마인드 하고자 했다.

  1. 학습 내용
    python의 경우, 기초적인 코딩 방법을 확인해보고, 실제로 자주 사용되는 예시들을 시청했다. 꽤나 많은 양의 지식들이었지만 이해하기 쉽게 설명해주시고, 강의 영상의 길이도 짧았기 때문에 부담없이 시청할 수 있었다.

SQL 또한 앞으로도 계속 사용할 예정이다. 그리고 꽤 익숙해졌다고는 해도, 아직 SQL을 다루는 데에는 초보자 수준에 불과하기 때문에 기초를 끊임없이 다져줘야 한다고 생각한다. 따라서 오늘은 투터님의 라이브 세션이 없는 날이기도 하니, 지금까지 배웠던 것들을 재점검하는 시간을 가져보았다.

  • 학습 주제: python 코딩 맛보기, 현재까지 배운 SQL 기초 개념 리마인드

  • 핵심 개념 정리:

  1. python 코딩은 굉장히 직관적이다. SQL과 마찬가지로(경우에 따라서는 SQL보다도) 간단하게 코드를 작성해서 원하는 값을 출력하는 게 가능하다.
  2. SQL 조건문, 정렬, 집계함수, 그룹화, sub query 개념을 복습했다. SQL의 기초이기 때문에 잘못 이해하면 앞으로 배울 내용들이 모두 무의미해질 가능성이 크다. 그렇기 때문에 꼼꼼하게 재확인해보는 시간을 가졌다.
  • 코드 예시 + 결과:
    python은 아직 설치를 하지 못했다. 추후 진행될 python 강의를 위해서 미리 설치해두는 것도 좋겠지만, 혹여나 라이브 세션에서 사용할 툴과 다른 것을 설치할 우려도 있다. 그러므로 후에 어떤 툴을 사용할 지 확인되면 설치하려고 한다.

SQL 복습은 이전 포스트에서 한 번 다뤘던 내용들이다. 따라서 이번 TIL에서는 문제와 내가 풀어낸 답을 확인해보는 과정을 간단하게 진행하도록 하겠다.

1. where 로 특정 조건을 만족하는 데이터 가져오기

성별이 '여자'인 데이터

  • 작성한 코드
select *
from basic.theglory 
where 성별 ='f'
;
  • 실행값

    2. case when 으로 컬럼에 조건 제시하기

이름이 '문동은'이거나 '주여정'인 경우 역할을 '선'으로, 아닌 경우 '악'으로 설정

  • 작성한 코드
select *, case when 이름 in('문동은', '주여정') then '선'
	else '악' end as '역할구분'
from basic.theglory 
;
  • 실행값

3. 조건문에 연산자 사용하기

날짜 데이터가 비어있지 않고, 성별이 남자가 아니고, 직업이 아나운서 또는 승무원 또는 화가이고, 나이가 30세에서 40세 사이(이상 , 이하)인 데이터

  • 작성한 코드
select *
from basic.theglory 
where (날짜 is not null)
	and (성별!='m')
	and (직업 in ('아나운서', '승무원', '화가'))
	and (나이 between 30 and 40)
;
  • 실행값

4. order by로 결과값 정렬하기

  • 작성한 코드 1
select 날짜, 이름, 성별, 나이, 직업
from basic.theglory
order by 1 desc
;
  • 실행값 1

  • 작성한 코드 2

select 날짜, 이름, 성별, 나이, 직업
from basic.theglory
order by 1 desc, 3 asc
;
  • 실행값 2

    위의 두 실행값을 자세히 보면 날짜가 내림차순으로 동일하게 되어 있다. 하지만 코드 2에서는 성별을 기준으로 오름차순 정렬을 한 번 더 해줬기 때문에 날짜가 같은 '최혜정'과 '전재준'이 성별 기준으로 재정렬 되어 있는 것을 볼 수 있다.

5. where 구문의 활용

'first_login_date' 컬럼이 '2023-01-01'를 초과하는 데이터의 'game_account_id', 'game_actor_id', 'serverno' 컬럼 추출하기

  • 작성한 코드
select game_account_id, game_actor_id, serverno
from basic.users 
where first_login_date>'2023-01-01'
;
  • 실행값

6. where 구문의 응용

아래 조건들을 모두 만족하는 데이터의 first_login_date, ip_addr, exp, zone_id 를 추출하고 first_login_date을 기준으로 내림차순으로 정렬하기
조건1) level 컬럼이 10 초과
조건2) serverno컬럼이 1이 아님
조건3) 아이템 이름 컬럼이 레벨업 패키지 또는 시즌패스
조건4) 아이템 획득 경로가 상점에서 구매한 경우

  • 작성한 코드
select first_login_date, ip_addr, exp, zone_id
from basic.users 
where (level>10)
	and (serverno!=1)
	and (etc_str2 in('레벨업 패키지', '시즌패스'))
	and (etc_str1='상점에서 구매')
order by first_login_date desc
;
  • 실행값

7. case when 구문의 활용

아래 조건을 만족하는 데이터의 game_actor_id, level, levelgroup, first_login_date 컬럼을 추출하고, first_login_date를 기준으로 내림차순 정렬하기
조건1) case when 구문을 사용하여 레벨구간을 아래와 같이 구분, 컬럼이름을 ‘levelgroup’ 으로 설정

[레벨구간]
◦ 1~10Lv 이하
◦ 11~20Lv 이하
◦ 21~30Lv 이하
◦ 31~40Lv 이하
◦ 41~50Lv 이하
◦ 51~60Lv 이하
◦ 61~70Lv 이하
◦ 71~80Lv 이하
◦ 81~90Lv 이하
◦ 91~100Lv

  • 작성한 코드
select game_actor_id, level,
	case when level <=10 then '1~10Lv 이하'
	     when level <=20 then '11~20Lv 이하'
		 when level <=30 then '21~30Lv 이하'
		 when level <=40 then '31~40Lv 이하'
		 when level <=50 then '41~50Lv 이하'
		 when level <=60 then '51~60Lv 이하'
		 when level <=70 then '61~70Lv 이하'
		 when level <=80 then '71~80Lv 이하'
		 when level <=90 then '81~90Lv 이하'
		 else '91~100Lv' end as levelgroup, first_login_date
from basic.users 
order by first_login_date desc 
;
  • 실행값

8. 집계함수 및 그룹화 활용하기

성별을 기준으로 전체 데이터의 갯수, 평균 나이, 최대 나이, 최소 나이, 나이 합계 구하기

  • 작성한 코드
select 성별,
	count(*) as cnt,
	avg(나이) as '평균 나이',
	max(나이) as '최대 나이',
	min(나이) as '최소 나이',
	sum(나이) as '나이 합계'
from basic.theglory
group by 1
;
  • 실행값

9. having으로 그룹화에 의한 데이터 결과 필터링하기

나이가 31 이상, 성별을 기준으로 평균 나이를 계산하고, 평균 나이가 41 초과인 경우 구하기
-작성한 코드

select 성별,
	avg(나이) as '평균 나이'
from basic.theglory
where 나이>=31
group by 1
having avg(나이)>41
;
  • 실행값

10. 인라인 뷰 subquery 활용하기

나이가 33세 이상인 모든 데이터 중 나이와 직업 컬럼 반환하기

  • 작성한 코드
select a.나이, a.직업
from (select *
	  from basic.theglory
	  where 나이>=33
	 ) as a
;
  • 실행값

11. 집계함수의 활용

아래 조건을 만족시켜 월별, 서버별 게임계정id 수를 중복값 없이 추출하기
*월은 첫 접속일자 컬럼을 기준으로
조건1) 월은 yyyy-mm의 형태로 추출

  • 작성한 코드
select substr(first_login_date, 1, 7) as m,
       serverno,
       count(distinct game_account_id) as usercnt
from basic.users 
group by 2, 1
;
  • 실행값

12. 집계함수와 조건절의 활용 1

group by 를 활용해 첫 접속일자별 게임 캐릭터 수를 중복값 없이 구하고, having 절을 사용해서 그 값이 10개를 초과하는 경우만 추출하기

  • 작성한 코드
select first_login_date,
       count(distinct game_actor_id) as actor_cnt
from basic.users
group by 1
having count(distinct game_actor_id)>10
;
  • 실행값

13. 집계함수와 조건절의 활용 2

group by 절을 사용하여 서버별, 유저구분(기존/신규)별 게임캐릭터id수 및 평균레벨을 추출하기(게임캐릭터id수는 중복값을 허용하지 않는 고유한 갯수로 추출할 것)

조건1) 기존/신규 기준→ 첫 접속일자가 2024-01-01 보다 작으면(미만) 기존유저, 그렇지 않은 경우 신규유저

  • 작성한 코드
select serverno,
       case when first_login_date<'2024-01-01' then '기존유저' 
            else '신규유저' end as gb,
       count(distinct game_actor_id) as actor_cnt,
       avg(level) as avg_level
from basic.users
group by 1, 2
;
  • 실행값

14. subquery의 활용

12번 문제를 having 이 아닌 인라인 뷰 subquery를 사용하여 추출하기

  • 작성한 코드
select *
from( select first_login_date,
             count(distinct game_actor_id) as actor_cnt
      from basic.users
      group by 1
    ) as a 
where a.actor_cnt>10
;
  • 실행값

위 사진을 통해 해당 코드의 실행값이 문제 12번의 실행값과 동일한 결과를 추출한 것을 확인할 수 있다.

15. subquery의 응용

  1. 레벨이 30 이상인 캐릭터를 기준으로, 게임계정 별 캐릭터 수를 중복값 없이 추출하기
  2. having 구문을 사용하여 계정별 캐릭터 수가 2개 이상인 경우만 추출하기
  3. 인라인 뷰 서브쿼리를 활용하여 캐릭터 수 별 게임계정 개수를 중복값 없이 추출하기
  • 작성한 코드
select a.actor_cnt, 
       count(*) as accnt
from ( select u.game_account_id,
              count(distinct u.game_actor_id) as actor_cnt
       from basic.users as u
       where level>=30
       group by 1
       having count(distinct u.game_actor_id)>=2
) as a
group by 1
order by 1
;
  • 실행값
  • 이번 학습을 진행하면서 느낀 점
    모든 문제에 대해서 조건에 부합하는 데이터를 추출하는 것에 성공했다.

    하지만 눈에 보이는 데이터가 원하던 데이터와 완전히 부합한다고 생각하는 것은 위험하다. 같은 값이더라도, 그 데이터가 포함하는 의미는 다를 가능성이 존재한다.

    가령 15번 문제의 경우 인라인 뷰 서브쿼리의 having 에서
    "count(distinct u.game_actor_id)" 가 아니라
    "count(game_account_id)" 를 입력한다고 해도 같은 실행값을 가지게 된다.

    이것이 문제가 되는 이유는 둘이 데이터를 추출할 때 대상이 되는 데이터가 다르기 때문이다.

    "having count(distinct u.game_actor_id)>=2" 는 "계정이 가지고 있는 캐릭터가 동일한 캐릭터를 제외하고 2개 이상인 경우"를 뜻한다.

    "having count(game_account_id)>=2" 는 "계정 데이터의 행 수가 2개 이상인 경우"를 뜻한다.

    즉, 전자일 때는 15번 문제의 두 번째 조건인 "계정별 캐릭터 수가 2개 이상인 경우만 추출"하는 것을 만족하지만, 후자일 때는 "계정별 캐릭터 수가 2개 이상인 경우"가 아니라 "계정이라는 데이터의 값이 2개 이상 있을 경우"를 의미하기 때문에 정확히 조건과 일치하지 않는다.

    쉽게 말해 후자는 "동일한 게임 캐릭터이지만 레벨이 다른 경우"도 포함하고 있기 때문에 조건에 완전히 부합하지는 않는다고 할 수 있다.

    이렇듯 추출된 값이 동일해보인다 해도, 그 내용을 당장에 완전히 신뢰할 수는 없다. 아무리 잘 쓰인 코드라도, 의뢰와는 동떨어진 의미를 가질 수 있기 때문이다. 이는 데이터의 신뢰성에 부정적인 영향을 주게 되고, 무엇보다 작업 시간을 대폭 늘리는 결과를 초래할 수 있다.

    이를 방지하기 위해서 다른 팀원들과의 크로스 체크를 습관화하고, 다른 것보다도 데이터 리터러시 능력을 길러야만 할 것이다.

  1. 내일 학습할 것은 무엇인지
    내일은 튜터님의 라이브 세션이 예정되어 있다. 따라서 내일 진행되는 강의 내용을 따라서 실습을 진행하게 될 듯하다.

    마치며 : 데이터 분석가 캠프 과정을 시작한 지 어느덧 열흘 째가 되었다. 무엇인가에 집중하고 몰두하니 시간이 참 빠르게 지나간다. 시간이 흘러 프로젝트를 진행하게 되는 날에는 이 감각이 더욱 강해질 것이다. 그러고보니 벌써 10월도 끝나간다. 올 한 해를 잠시 뒤돌아보고, 남은 두 달을 어떻게 보내야할 지 잠깐 생각해보고, 다시 힘차게 살아가보자.

profile
국문과 전공 데이터 입문자

0개의 댓글