본문 바로가기
개발/오라클

오라클 - 임의의 순서로 정렬하기 order by decode, order by case

by 루 프란체 2018. 3. 17.

이거 완전 신기방기하다. 이런 게 있다는 걸 왜 지금까지 몰랐을까?

알았다면 굳이 어렵게 쿼리를 두 번을 돌려가며 union 을 안 써도 됐을텐데...


어쨌든 order by decode 를 사용하게 된 상황은 다음과 같다.

아래와 같은 데이터가 있다고 하자.


 결제일

상품 

결제상태 

2018.03.16

검은사막 모바일

배송 중

2018.03.14

슈퍼판타지워

배송 완료

2018.03.10

개그콘서트

환불

2018.02.15

비트코인 떡상 가즈아

환불

2018.02.13

티스토리 편집기 불편

배송 완료

2018.02.11

여의도 벚꽃 놀이

배송 완료

2018.02.10

우리나라 좋은 나라

환불

2018.02.07

게임을 하면 이겨야지

배송 중


위 데이터는 결제일을 기준으로 order by 결제일 desc 를 한 결과이다.


그런데 다음과 같은 요청이 왔다.

"기존 정렬은 유지해주시되, 배송 완료인 상품을 제일 위로 올려서 보여주세요."


응? 그건 또 어떻게 하는건가?

그래서 생각한 아주 심플한 방법이 기존 쿼리에 status 조건을 넣어 배송 중인 것 따로 나머지 따로 쿼리를 돌려

union 으로 뚜까 초인합체를 시도하면 해결되지 않을까 하는 방법이었는데...


그런데 생각해보니 우리 DB는 엄청 느리다. 정확히는 DB Link 로 연결된 테이블에서 가져와야 하는데

그냥 느린 정도가 아니라 화면 상에 부하가 걸릴 정도로 엄청나게 느리다. 그래서 조언을 구한 결과...


order by decode(결제상태, '배송 완료', 1, 2) 로 해보세요. 

그래서 말 잘 듣는 나는 그대로 해봤다. 그랬더니...!!!


 결제일

상품 

결제상태 

2018.03.14

슈퍼판타지워

배송 완료

2018.02.13

티스토리 편집기 불편

배송 완료

2018.02.11

여의도 벚꽃 놀이

배송 완료

2018.03.16

검은사막 모바일

배송 중

2018.03.10

개그콘서트

환불

2018.02.15

비트코인 떡상 가즈아

환불

2018.02.10

우리나라 좋은 나라

환불

2018.02.07

게임을 하면 이겨야지

배송 중


원하는 대로 정렬이 되었다.

아, 물론 위의 구문을 그대로 쓴 건 아니고 결제일로도 정렬이 되어야 하기 때문에 실제로는

order by decode(결제상태, '배송 완료', 1, 2) asc, reg_dt desc 와 같이 변경해서 사용 했다.

그리고 혹시 몰라 시도해봤더니 order by decode(결제상태, '배송 완료', 1) asc, reg_dt desc 이렇게도 사용이 가능했다.


이왕 새로운 것을 알아가는 김에 조금 더 확실하게 알아두고 싶어서

order by decode(결제상태, '배송 완료', 1, '배송 중', 2) asc, reg_dt desc 이런 정렬도 시도해보니 결과는 다음과 같았다.


 결제일

상품 

결제상태 

2018.03.14

슈퍼판타지워

배송 완료

2018.02.13

티스토리 편집기 불편

배송 완료

2018.02.11

여의도 벚꽃 놀이

배송 완료

2018.03.16

검은사막 모바일

배송 중

2018.02.07

게임을 하면 이겨야지

배송 중

2018.03.10

개그콘서트

환불

2018.02.15

비트코인 떡상 가즈아

환불

2018.02.10

우리나라 좋은 나라

환불


앞으로도 아주 유용하게 사용할 수 있을 것 같다.


그리고 조금 더 찾아보니 order by decode 외에 order by case 라는 게 있다는 것도 알아냈는데...

decode 와 case 는 셀렉트 구문에서 사용하는 방법이 거의 비슷하니 아마도 이 구문도 비슷하게

이렇게 order by case(어쩌고~~) asc, reg_dt desc 이렇게도 사용이 가능하지 않을까 생각했는데 decode 와는 다르게 

order by (case 결제상태 when '배송 완료' then 1 when '배송 중' then 2 else 3 end) 이런 식으로 괄호 안에 넣어 사용해야 했다.

결과값은 물론 decode 를 사용했을 때와 동일.


그리고 이 쯤 되면 또다시 새로운 의구심이 든다. 

날짜와 order by 위치를 변경해서 사용하면 어떻게 될까?

원래 새로운 것을 배우면 이것저것 시도해야 하는 법이다.


order by reg_dt desc, decode(status, '배송 완료', 1, '배송 중', 2, 3);

새로운 시도를 위해 검은사막 모바일 운영 폭망이라는 row 를 3월 14일의 환불로 추가하고 시도해봤다.

(아 진짜 환불하고 싶다.)


 결제일

상품 

결제상태 

2018.03.16

검은사막 모바일

배송 중

2018.03.16

검은사막 모바일 운영 폭망

환불

2018.03.14

슈퍼판타지워

배송 완료

2018.03.10

개그콘서트

환불

2018.02.15

비트코인 떡상 가즈아

환불

2018.02.13

티스토리 편집기 불편

배송 완료

2018.02.11

여의도 벚꽃 놀이

배송 완료

2018.02.10

우리나라 좋은 나라

환불

2018.02.07

게임을 하면 이겨야지

배송 중


날짜 순으로 정렬이 된 후 그 안에서 배송 중이 먼저 정렬이 된 것을 알 수 있다.


2018-03-17 order by decode 테스트 데이터 생성.sql

댓글