<div>MariaDB에서 RANK() ORVER PARTITION BY 흉내 내기</div> <div><br></div> <div>MariaDB는 RANK() 함수를 지원하지 않습니다. 그래서 비슷하게 출력하는 쿼리 방법을 고안해 보았습니다.</div> <div><br></div> <div>MariaDB는 쿼리문 내에서 변수를 만들어 쓸 수 있기 때문에 RANK()는 쉽게 구현이 됩니다만, PARTITION BY는 간단치 않습니다.</div> <div><br></div> <div>예를 들어 국회의원 테이블에서 국민에게 막말 많이 한 순으로 순번을 붙여 추출하면 다음과 같을겁니다.</div> <div><br></div> <div><span class="Apple-tab-span" style="white-space:pre;"> </span>SELECT 이름</div> <div><b><span class="Apple-tab-span" style="white-space:pre;"> </span>, @RANK := @RANK+1 </b></div> <div><span class="Apple-tab-span" style="white-space:pre;"> </span>FROM 국회의원테이블</div> <div><span class="Apple-tab-span" style="white-space:pre;"> </span>WHERE 기준연월 = '201511'</div> <div><span class="Apple-tab-span" style="white-space:pre;"> </span>ORDER BY 막말횟수 DESC</div> <div><br></div> <div>이름<span class="Apple-tab-span" style="white-space:pre;"> </span>RANK</div> <div>------------</div> <div>이완영<span class="Apple-tab-span" style="white-space:pre;"> </span>1</div> <div>김무성<span class="Apple-tab-span" style="white-space:pre;"> </span>2</div> <div>이정현<span class="Apple-tab-span" style="white-space:pre;"> </span>3</div> <div>...</div> <div><br></div> <div>여기까지는 어렵지 않습니다.</div> <div><br></div> <div>이 때 전체 국회의원을 대상으로 하지 않고 정당별로 순위을 매기고 싶다면 어떻게 할까요?</div> <div>일단 정당을 추가해 보겠습니다. 그리고 정당, 막막횟수 순으로 출력하겠습니다.</div> <div><br></div> <div><span class="Apple-tab-span" style="white-space:pre;"> </span>SELECT 정당, 이름</div> <div><span class="Apple-tab-span" style="white-space:pre;"> </span>, @RANK := @RANK+1 </div> <div><span class="Apple-tab-span" style="white-space:pre;"> </span>FROM 국회의원테이블</div> <div><span class="Apple-tab-span" style="white-space:pre;"> </span>WHERE 기준연월 = '201511'</div> <div><b><span class="Apple-tab-span" style="white-space:pre;"> </span>ORDER BY 정당, 막말횟수 DESC</b></div> <div><br></div> <div>정당 이름<span class="Apple-tab-span" style="white-space:pre;"> </span>RANK</div> <div>----------------------</div> <div>새누리<span class="Apple-tab-span" style="white-space:pre;"> </span>이완영<span class="Apple-tab-span" style="white-space:pre;"> </span>1</div> <div>새누리<span class="Apple-tab-span" style="white-space:pre;"> </span>김무성<span class="Apple-tab-span" style="white-space:pre;"> </span>2</div> <div>새누리<span class="Apple-tab-span" style="white-space:pre;"> </span>이정현<span class="Apple-tab-span" style="white-space:pre;"> </span>3</div> <div>...</div> <div><b>새누리<span class="Apple-tab-span" style="white-space:pre;"> </span>ZZZ<span class="Apple-tab-span" style="white-space:pre;"> </span>158</b></div> <div><b>새정치<span class="Apple-tab-span" style="white-space:pre;"> </span>XXX<span class="Apple-tab-span" style="white-space:pre;"> </span>159</b></div> <div>새정치<span class="Apple-tab-span" style="white-space:pre;"> </span>YYY<span class="Apple-tab-span" style="white-space:pre;"> </span>160</div> <div>...</div> <div><br></div> <div>정의당과 무소속도 있지만 국회의원테이블에는 교섭단체만 들어 있다고 칩시다.</div> <div><br></div> <div>새정치는 XXX 의원이 1등, YYY 의원이 2등이네요. 우리가 원하는 결과는 아래와 같이 정당별로 순번을 새로 매기는건데 아직 부족하네요.</div> <div><br></div> <div>정당 이름<span class="Apple-tab-span" style="white-space:pre;"> </span>RANK</div> <div>----------------------</div> <div>새누리<span class="Apple-tab-span" style="white-space:pre;"> </span>이완영<span class="Apple-tab-span" style="white-space:pre;"> </span>1</div> <div>새누리<span class="Apple-tab-span" style="white-space:pre;"> </span>김무성<span class="Apple-tab-span" style="white-space:pre;"> </span>2</div> <div>새누리<span class="Apple-tab-span" style="white-space:pre;"> </span>이정현<span class="Apple-tab-span" style="white-space:pre;"> </span>3</div> <div>...</div> <div>새누리<span class="Apple-tab-span" style="white-space:pre;"> </span>ZZZ<span class="Apple-tab-span" style="white-space:pre;"> </span>158</div> <div><b>새정치<span class="Apple-tab-span" style="white-space:pre;"> </span>XXX<span class="Apple-tab-span" style="white-space:pre;"> </span>1</b></div> <div>새정치<span class="Apple-tab-span" style="white-space:pre;"> </span>YYY<span class="Apple-tab-span" style="white-space:pre;"> </span>2</div> <div>...</div> <div><br></div> <div>쿼리문을 다음과 같이 고칩니다.</div> <div><br></div> <div><span class="Apple-tab-span" style="white-space:pre;"> </span>SELECT 정당, 이름</div> <div><b><span class="Apple-tab-span" style="white-space:pre;"> </span>, CASE WHEN @PARTITION = 정당 THEN </b></div> <div><b><span class="Apple-tab-span" style="white-space:pre;"> </span>@RANK := @RANK+1 </b></div> <div><b><span class="Apple-tab-span" style="white-space:pre;"> </span> ELSE </b></div> <div><b><span class="Apple-tab-span" style="white-space:pre;"> </span> @RANK := 1 </b></div> <div><b><span class="Apple-tab-span" style="white-space:pre;"> </span> END RANK </b></div> <div><b><span class="Apple-tab-span" style="white-space:pre;"> </span>, @PARTITION := 정당</b></div> <div><span class="Apple-tab-span" style="white-space:pre;"> </span>FROM 국회의원테이블</div> <div><span class="Apple-tab-span" style="white-space:pre;"> </span>WHERE 기준연월 = '201511'</div> <div><span class="Apple-tab-span" style="white-space:pre;"> </span>ORDER BY 정당, 막말횟수 DESC</div> <div><br></div> <div>@PARTITION 이라는 변수를 추가하고 CASE WHEN문으로 이전 정당과 같은지 비교합니다.</div> <div>같으면 하던대로 @RANK를 1 증가시키고, 다르면 @RANK를 1부터 새로 매깁니다.</div> <div><br></div> <div>이제 원하는 결과가 나옵니다. </div> <div><br></div> <div>만약 전체 다 뽑지 않고 정당별로 TOP 3 만 뽑으려면 Inline view로 만들어서 RANK 값을 필터링 하면 됩니다.</div> <div><br></div> <div><b><span class="Apple-tab-span" style="white-space:pre;"> </span>SELECT * </b></div> <div><b><span class="Apple-tab-span" style="white-space:pre;"> </span>FROM (</b></div> <div><span class="Apple-tab-span" style="white-space:pre;"> </span>SELECT 정당, 이름</div> <div><span class="Apple-tab-span" style="white-space:pre;"> </span>, CASE WHEN @PARTITION = 정당 THEN </div> <div><span class="Apple-tab-span" style="white-space:pre;"> </span>@RANK := @RANK+1 </div> <div><span class="Apple-tab-span" style="white-space:pre;"> </span> ELSE </div> <div><span class="Apple-tab-span" style="white-space:pre;"> </span> @RANK := 1 </div> <div><span class="Apple-tab-span" style="white-space:pre;"> </span> END RANK </div> <div><span class="Apple-tab-span" style="white-space:pre;"> </span>, @PARTITION := 정당</div> <div><span class="Apple-tab-span" style="white-space:pre;"> </span>FROM 국회의원테이블</div> <div><span class="Apple-tab-span" style="white-space:pre;"> </span>WHERE 기준연월 = '201511'</div> <div><span class="Apple-tab-span" style="white-space:pre;"> </span>ORDER BY 정당, 막말횟수 DESC</div> <div><span class="Apple-tab-span" style="white-space:pre;"> </span>) A</div> <div><b><span class="Apple-tab-span" style="white-space:pre;"> </span>WHERE A.RANK <= 3</b></div> <div><br></div> <div>여기까지 입니다. RANK() OVER PARTITION BY에 비하면야 많이 불편하지만 도움이 되길 바랍니다.</div> <div><br></div>
위 쿼리 결과는 단지 샘플일 뿐입니다.
오늘 신문을 보니 김무성이 시위에 나선 국민을 IS에 비유했더군요.
댓글 분란 또는 분쟁 때문에 전체 댓글이 블라인드 처리되었습니다.