본문 바로가기
국비교육기관/수업

08일차_파이썬_Numpy_Pandas / 오라클 SQL_서브쿼리

by 밀키스 2021. 3. 24.

@21.03.24

@Numpy

@불린색인

Numpy에서의 불린 색인은 그냥 위 사진 처럼 True인 값에 대한 array 값을 반환하는 것.

 

@Numpy 예제 - 평점 구하기

위와 같이 "loadtxt"라는 명령어를 통해 ratings.txt 데이터 파일을 불러와 푸는 문제이다. 불러올 때에 텍스트 파일이 콜론 2개를 사용해 데이터 값을 구분짓기 때문에 "delimiter"를 통해 column을 나눴다.

위에서 user_data 변수에 담는 부분을 보면 data_movie의 1번 열의 값이 i인 모든 행을 반환한다는 뜻이다.

데이터 파일을 기준으로 보면 이는 user_id가 i와 일치할 때를 뽑는 것이고 때문에, temp_score에 담기는 값은 해당 user_id의 3번째열인 평점에 대한 평균 값을 구하는 양상이다.

이로써 4점 이상인 평점을 리스트에 추가하고 평점이 4점 이상인 고객들을 모두 반환하는 문제.

 

%dtype

문제 자체를 푸는건 어렵지 않았다마는 출력했을 때에 데이터 형태가 e를 포함한 형태로 나와 당황했다. 데이터 타입을 변환하기 위한 "dtype"의 경우는 원래 한가지 값만 바꿀 수 있다 하지만 help를 통해 소스코드 부분 예제를 보면

이런 부분이 있다. 때문에 좀 더 보면.... 알것도 같은데.. 한번 확인 한번 해봐야겠다.

 

@Pandas

@Pandas

데이터 조작 및 분석을 위한 라이브러리
                     -Series Class: 1차원        =>  인덱스 + 값(Value)
                     -DataFrame Class: 2차원  =>  행과 열을 가지는 표와 같은 형태
                                                        =>  서로 다른 종류의 자료형을 저장할 수 있음

 

@Series

Pandas 안의 명령어 Series를 통해서 인덱스를 포함한 데이터 형태를 만들 수 있다. 위와 같이 index를 지정해주지 않으면 자동으로 0번부터 숫자가 달린다.

 

@Values / Index / dtype / name

Values는 단어 그대로 내가 생성한 Series의 Value값을 반환하는 명령어.

 

index와 dtype은 각각 index의 값과 type형을 반환한다.

 

name 명령어의 경우는 내가 만든 Series에 이름을 부여한다. 보면 알겠지만 index의 상단부에도 이름을 붙일 수 있으며 Series 자체의 이름 또한 하단에 표기된다.

 

@인덱싱 & 슬라이싱

사진을 보면 알겠지만 Series의 값을 인덱싱할때에 특정 인덱스의 번호뿐만 아니라 인덱스의 "값"을 불러도 위와 같이 호출할 수 있다.

 

@Boolean Indexing(색인)

저렇게 Series에 대한 논리기호를 통해 Value값이 Bool 값인 Series로 반환할 수 있으며, 해당 Series를 대괄호로 감싸면 Bool값이 True인 값만 반환하는 Series를 생성할 수 있다.

 

@Series에서의 사잇값 구하기

일단 보면 Series의 사잇값을 반환토록하기 위한 구문은 위와 같다. ( -> & <- )자바에서 처럼 and를 쓰지 않고 저래 표현하는가?... 음... 

무튼 단정 짓자면 " a < 값 < b " 나 " and " 를 이용한 구조는 통용되지 않는다.

 

같은 의미로

or 연산자 =>

not 연산자 =>

로 쓴다.

 

아래는 Numpy 및 Pandas의 주피터 노트북이다.

Numpy

Pandas

 

=======================================================

 

오라클 SQL

@SQL 연습문제

21. 매니저로 근무하는 사원들의 총 수를 출력하시오

매니저로 근무하는 사원의 수. 즉, 매니저직을 겸한 사원 수가 몇명이냐 묻기 때문에 manager_id를 count해준다.

근데, manager_id 중에서 또 중복되는게 있기 때문에 distinct 구문을 통해 중복되는걸 걸러주고 카운팅할 것.

 

22. 사내의 최대 급여 및 최소 급여의 차이를 출력하시오.

급여의 최대값과 최소값의 차이를 구하는 문제. max와 min을 이용해 해결하였다.

 

23.매니저의 사번 및 그 매니저 밑 사원들 중  최소 급여를 받는 사원의 급여를 출력하시오

     - 매니저가 없는 사람들은 제외한다.

     - 최소 급여가 5000미만인 경우는 제외한다.

     - 급여 기준 역순으로 조회한다.

우선 매니저의 사번과 최소급여이기 때문에 select는 위와 같이 설정. employee_id가 곧 manager의 사번이니까.manager_id가 null로 존재하는 행도 있기 때문에 where절은 위와 같이 설정.manager의 밑 사원들은 자신의 행에 해당 manager_id를 갖고 있기 때문에 그룹화는 manager_id로 설정각 매니저의 밑 사원들 중의 봉급이기 때문에, 행 단위가 아닌 그룹단위로 조건을 걸 수 있는 HAVING절을 사용하여 최소값이 5000미만이 되지 않도록 조건을 건다.

 

24. 부서명, 부서위치ID, 각 부서 별 사원 총 수, 각 부서 별 평균 급여를 출력하되, 부서위치를 오름차순으로 출력하시오

select d.department_name, d.location_id, count(e.employee_id), avg(e.salary)
from departments d, employees e
where d.department_id = e.department_id
group by d.department_name, d.location_id
order by d.location_id

일다느으은... 그룹화를 2개를 해줬는데....... 왜??...

일단 막약 부서이름만 그룹화를해서 출력하면 11개, 지역번호만 그룹화해서 출력하면 7개가 나오는데, 2개를 같이 그룹화해서 부서이름, 지역번호 중 하나만 출력하면 11개가 나온다.

이 뜻은 갯수가 적은 놈이 많은 놈한테 맞춰가는 느낌일까??..

무튼 결론적으로 보면 내가 출력하고 싶은건 지역번호고 그룹화는 부서이름만 했다면 안된다는 거. 내가 지역번호까지 출력하고 싶다면 지역번호까지 그룹화해야 하는것 같다.

결국 GROUPBY절에 대한 이해가 너무 부족한것 같다. 한번 더 볼것.

6. 서브 쿼리

@서브쿼리

- select문 안에 하나의 혹은 여러개의 select문을 더 넣는 것, 포함시키는 것.

- 서브쿼리가 메인쿼리보다 먼저 발동이 되고, 메인쿼리로 넘어간다.

- 물론 더 넣을수록 성능이 좋을 수는 없으나 'JOIN' 보다는 훨씬 좋은 성능을 보인다

간단한 예.

select last_name, salary
from employees
where salary > ( select salary
		from employees
		where last_name = 'Abel')

'Abel'이란 이름을 갖는 사원의 봉급보다 많은 봉급을 받는 사원을 찾는 구문. 해당 사원의 봉급을 서브쿼리를 통해 찾은 모습이다.

 

@서브쿼리의 유형

단일 행 서브쿼리: =과 같은 연산자 사용

다중 행 서브쿼리: in과 같은 연산자 사용

@단일 행 서브쿼리

- 단일 행 서브쿼리는 결국 내가 필요한 값을 위함.

- 내가 뭘 모르는지, 뭘로 반환하면 되는지에 대해서 고민

select last_name, department_id, salary
from employees
where department_id = (select department_id
			from departments
			where department_name = 'IT')

위는 " IT라는 부서에 근무하는 사원의 이름과 부서번호, 급여를 출력 "하는 구문이다. 원레 같으면 JOIN으로 해결을 해야 하지만 서브쿼리를 통해 해결을 한 모습이다.

 

%주의할 것.

위 구문은 틀린 구문이다. 한번 보면 부서번호를 그룹화 시켜주면 당연히 각 그룹별 정리가 될테고, 여기서 min을 통해 봉급을 출력하면 각 부서별 최소 봉급이 나온다. 즉, 부서수만큼의 min(salary)를 한개의 salary와 비교하는 식이기 때문에 오류가 날 것.  서브쿼리를 통해 출력되는 결과에 대해서는 항상 확인.

 

@다중행 서브쿼리

- 다중 행 서브쿼리는 값이 아닌 음... 파이썬으로 비교하면 튜플이나 리스트 처럼 여러 값, 여러 행(ROW)를 반환하는 것.


%ANY와 ALL

만약 서브쿼리 반환 값이 (30, 40)이고, 10~60까지 10단위로 있을 때

SQ = (30, 40)   /   list -> 10, 20, 30, 40, 50, 60

 list > ANY(SQ) : (최소값 30보다 큰 값) => 40, 50, 60    

 list < ANY(SQ) : (최대값 40보다 작은 값) => 10, 20, 30  

 list > ALL(SQ)  : (전부 최대값 40보다 큰 값) => 50, 60    

 list < ALL(SQ)  : (전부 최소값 30보다 작은 값) => 10, 20 

 

@SQL 연습문제 - 서브쿼리

25. Zlotkey와 동일한 부서에 근무하는 다른 모든 사원들의 사번 및 고용날짜를 출력하시오.

일단 서브쿼리를 통해 Zlotkey가 어떤 부서에 근무하는지 알아야 한다.

서브쿼리에서 본 것은 last_name의 값이 'Zlotkey'인 부서번호를 반환시켰고, 해당 값을 갖는 사원의 부서번호와 입사 날짜를 출력하였다.

근데 내가 위에서 잘못 생각한게 있는데... last_name이 'Zlotkey'인 사람이 1명이 아닐 수 있다는 것. 때문에 =가 아닌 in을 써야한다는 점과... 기껏 사번과 고용일자 다 뽑았는데 문제 자체가 Zlotkey와 동일한 사람이잖은가. 그러니까 last_name이 Zlotkey인 사람은 제외 할것... 2가지다.

 

26. 회사 전체 평균 급여보다 더 많이 받는 사원의 사번 및 이름

처음에는 SQ 밖에다가 열심히 AVG를 쓰려했다. 그러면 안되고... 보이는 것과 같이 SQ안에서 전체 평균 급여를 구해서 salary > SQ 일케 비교해야 한다.

 

27. 이름에 u가 포함되는 사원들과 동일 부서에 근무하는 사원들의 사번 및 이름을 출력

우선 SQ를 통해 이름에 u가 들어가는 사원들의 부서를 알아야하는데, 주의해야할건 u가 포함하는 사원이 1명이 아닌 것. 때문에, 반환되는 부서 또한 한개가 아닌 다수개일 수 있다. 결론적으로는 그때문에 where절에서 =가 아닌 in을 쓸 것.

 

 

 

 

 

 

 

 

 

 

 

 

!! GROUP BY절에 대한 내용 좀 더 숙지할 것!!

반응형

댓글