기본 콘텐츠로 건너뛰기

개발 공부 - 윈도우 함수

0.1. 윈도우 함수(Window Function)란?

우선 윈도우 함수가 무엇인지 아주 간단하게 설명하고 넘어가도록 하겠습니다.
윈도우 함수의 정의를 찾아보면 다음과 같습니다.

윈도우 함수(Window Function)
= 행과 행간의 관계를 쉽게 정의 하기 위해 만든 함수를 이름

기존의 SQL 언어는 컬럼과 컬럼간의 연산, 비교, 집계에 특화되어있는 언어였습니다.
반면 행과 행간의 관계를 정의하거나 비교, 연산하는 것은 하나의 SQL 문으로 처리하기 어려웠죠.
이러한 부분을 쉽게 처리하기 위해 생겨난 것이 윈도우 함수입니다.

윈도우 함수의 생김새를 살펴보면 아래와 같습니다.

함수(컬럼) OVER (Partition by 컬럼 Order by 컬럼)

함수 : Min, Max, Sum, Count, Rank 등과 같은 기존의 함수 or 윈도우 함수용으로 추가된 함수 (Row_number 등)
OVER : over 은 윈도우 함수에서 꼭 들어가야 하며 Over 내부에 Partition By 절과 Order by 절이 들어갑니다.
partition by : 전체 집합을 어떤 기준(컬럼)에 따라 나눌지를 결정하는 부분.
order by : 어떤 항목(컬럼)을 기준으로 순위를 정할 지 결정하는 부분

적용할 함수와 Over 절은 윈도우 함수에서 필수적으로 사용되며, 어떤 결과를 만들어낼지에 따라 partition by 와 order by 절을 사용하게 됩니다.



group by 와 윈도우 함수의 가장 큰 차이는 '집약'의 과정이 존재하는가? 입니다.
예시를 활용해 이해를 해봅시다.
< group by 를 사용한 경우>

select address, count(*)
from address
group by 1;
group by 의 경우

< 윈도우 함수를 이용한 경우 >

select address , count(*) over(partition by address)
from address;
윈도우 함수의 경우

위 두 경우를 살펴보면 차이점을 알 수 있습니다.
group by 는 집약 기능으로 인해 행 수가 줄어든 반면, 윈도우 함수는 행 수가 그대로 남아있습니다.
윈도우 함수에는 집약의 기능이 없기 때문입니다.
이러한 특징을 이용해서 우리는 행과 행간의 관계를 편하게 다룰 수 있게 됩니다!




  • 윈도우 함수는 행과 행 간의 관계를 정의하기 위해서 제공되는 함수
  • 윈도우 함수를 사용해서 순위, 합계, 평균, 행 위치 등을 조작할 수 있다.
  • 윈도우 함수는 GROUP BY 구문과 병행하여 사용할 수 없다.
  • 윈도우 함수로 인해 결과 건수가 줄어들지는 않는다.
  • WINDOW 함수의 PARTITION 구문과 GROUP BY 구문은 둘 다 파티션을 분할한다는 의미에서는 유사하다.
  • sum, max, min 등과 같은 집계 윈도우 함수를 사용할 때 윈도우 절과 함께 사용하면 집계 대상이 되는 레코드 범위를 지정할 수 있다.


윈도우 함수 구조

SELECT WINDOW_FUNCTION(ARGUMENTS)
  OVER (PARTITION BY 칼럼
     ORDER BY WINDOWING절)
FROM 테이블명;

구조설명
ARGUMENTS(인수)윈도우 함수에 따라서 0~N개의 인수를 설정한다.
PARTITION BY전체 집합을 기준에 의해 소그룹으로 나눈다
ORDER BY어떤 항목에 대해서 정렬한다
WINDOWING- 행 기준 범위를 정한다
ROWS는 물리적 결과의 행 수이고 RANGE는 논리적인 값에 의한 범위이다.

WINDOWING

구조설명
ROWS부분집합인 윈도우 크기를 물리적 단위로 행의 집합을 지정한다.
RANGE논리적 주소에 의해 행 집합을 지정한다.
BETWEEN~AND윈도우의 시작과 끝 위치를 지정한다.
UNBOUNDED PRECEDING윈도우 시작 위치가 첫 번째 행임을 의미한다.
UNBOUNDED FOLLOWING윈도우 마지막 위치가 마지막 행임을 의미한다.
CURRENT ROW윈도우 시작 위치가 현재 행임을 의미한다.
(데이터가 인출된 현재 행을 의미한다.)

WINDOWING 예시

전체합계

SELECT EMPNO, ENAME, SAL
SUM(SAL) OVER(ORDER BY SAL
    ROWS BETWEEN UNBOUNDED PRECEDING
    AND UNBOUNDED FOLLOWING) TOTSAL
FROM EMP;
  • UNBOUNDED PRECEDING은 처음 행을 의미하며, UNBOUNDED FOLLOWING은 마지막 행을 의미한다. 그러므로 TOTSAL의 처음부터 마지막까지의 합계(SUM(SAL))를 계산한 것이다.

누적합계

SELECT EMPNO, ENAME, SAL
SUM(SAL) OVER(ORDER BY SAL
    ROWS BETWEEN UNBOUNDED PRECEDING
    AND CURRENT ROW)TOTSAL
FROM EMP;
  • 처음부터 CURRENT ROW까지의 합계를 계산한다. 즉, 누적합계인 것이다.
  • 1째 행의 값이 1이었으면 1, 2째 행의 값이 2였으면 1+2=3, 3째 행의 값이 3이었으면 1+2+3=4 이렇게 계산된다.


* 프로그래머스에서 공부 중, Group By로 힘들게 구현했으나, 사실 윈도우 함수 쓰면 될 거 같다는 생각이 들어서 윈도우 함수도 공부해 둔다.

RANK는 생각보다 많이 썼던 것 같음!












출처 : https://velog.io/@yewon-july/Window-Function
https://schatz37.tistory.com/12


댓글

이 블로그의 인기 게시물

Ebook - 전자책 drm 상관 없이 pdf로 만들기

yes24와 교보문고에서 ebook을 구매 해야 했는데 너무 불편하고, 필기가 매우 화날 정도로 안 좋아서 원시적으로 사용하기로 했다. 1. 목적 : ebook에서 필기 및 사용이 불편하여 pdf로 변환  2. 용도 : 개인 사용 목적이며 화질이 다소 저하되어도 필기만 용이하면 상관 없음 3. 방법 1) 휴대폰 및 카메라로 동영상을 촬영했다. DRM 때문에 프로그램으로는 촬영이 안 되는 것을 확인했다. 2) 마우스 클릭 해주는 매크로를 사용했다. (1) key_macro.exe > https://blog.daum.net/pg365/250 듀얼 모니터에서 위치 이탈 현상이 있긴 해도 괜찮았다. (2) AutoClick.exe > http://bestsoftwarecenter.blogspot.com/2011/02/autoclick-22.html 이 걸로 잘 사용했다. 3초마다 한 번 클릭하도록 사용했다. 3) 동영상을 이미지로 변경해주는 프로그램을 사용했다. Free Video to JPG Converter > https://free-video-to-jpg-converter.kr.uptodown.com/windows 일 하면서 듀얼 모니터에 켜 놨는데 속도가 괜찮았다. * Every frame 으로 사용해야 한다. 4) 중복 사진 제거해주는 프로그램을 사용했다. VlsiPics  > http://www.visipics.info/index.php?title=Main_Page 생각보다 느리니 퇴근시에 걸어놓고 가면 된다. 한번 play가 끝나면 Auto-select 하고 Delete 하면 된다. 5) 이미지를 일괄 Crop 작업 해주는 프로그램을 사용했다. JPEGCrops > https://jpegcrops.softonic.kr/ * https://joker1209.tistory.com/11 도 참고했다. View -> Large 로 크게 본 뒤, Edit -> Syncronize Crops 로 일괄 동일하게 적용하는 방식을 사

개발 공부 - json JSONObject 사용 시 백슬래시(\), 원화 표시(\) 제거 및 치환

import org.json.simple.JSONObject; String dataString = new String(authData.toJSONString()); dataString = dataString.replaceAll("\\\\", ""); String 으로 안 바뀌는 가 싶어서 String 으로 변환 해 주고 작업 하였다. 사실 toJSONString 해도 정상 동작 해야 하는데 이유를 잘 모르겠음. 그리고 나서 다시 이클립스 구동 하니 toString 도 먹은 걸로 봐서 이상하다고 생각! String dataString = authData.toString(); dataString = dataString.replaceAll("\\\\", ""); 어쨌든 백 슬래시 제거를 해줘야 하는데 \\ 도 아니고 \\\\를 해야 변환이 가능했다는 결말이었습니다. 참고 : https://stackoverflow.com/questions/15450519/why-does-string-replace-not-work/15450539 test =test.replace("KP", "");  replace 후에 담아 주지 않으면 적용이 안 됩니다!

개발 공부 - OracleXETNSListener 서비스가 로컬 컴퓨터에서 시작했다가 중지되었습니다.

여러 가지 요인이 있지만 PC 이름 변경시 OracleXETNSListener 서비스 시작이 불가능합니다. 고치는 법은 C:\oraclexe\app\oracle\product\11.2.0\server\network\ADMIN 와 같은 설치 경로에서 listener.ora와 tnsnames.ora 의 pc명을 바꾼 PC명으로 바꿔주면 됩니다. 그래도 안 된다면 cmd 창에서 services.msc 를 입력 후 OracleXETNSListener 서비스를 시작 시키면 됩니다. 오류명: OracleXETNSListener 서비스가 로컬 컴퓨터에서 시작했다가 중지되었습니다. 일부 서비스는 다른 서비스 또는 프로그램에서 사용되지 않으면 자동으로 중지됩니다. 참고한 사이트들 1. http://blog.naver.com/visioner7/120165951652 2. http://database.sarang.net/?inc=read&aid=6819&criteria=oracle&subcrit=&id=&limit=20&keyword=ora-12560&page=5 이런 걸 보면 오라클은 앙칼진 시골 아가씨야