Backend/Database

Database - ORDER BY 커스텀 정렬

둉이 2021. 9. 14. 16:09

 

보통 ORDER BY 절에는 컬럼명 + [ASC | DESC] 형태로 정렬하고자 하는 기준 컬럼을 넣어서 사용한다.

 

기준 컬럼명만 넣어줄 경우(ORDER BY 컬럼명), 기본적으로 오름차순(ASC)으로 정렬된다.

 

혹은, 행 번호나 컬럼을 이용한 계산식 혹은 함수를 이용하여 정렬을 할 수도 있다.

 

계산식이나 함수 사용 예시는 다음과 같다.

order by LENGTH(CITY_CONT)  --해당 컬럼 길이 기준 오름차순 정렬
order by VAL1/VAL2  -- 수식으로 정렬
order by rand()  -- 랜덤 정렬(mysql)
order by 2, 1  -- 컬럼명 대신 SELECT 절에서 선택된 컬럼의 위치번호로 지정 가능
order by CITY_NAME LIKE '서%', CITY_NAME LIKE '광%'  -- 여러 조건식 지정 가능, 나머지 -> 조건2 -> 조건1 순으로 정렬

 

ORDER BY 절에는 저렇게 계산식이나 함수를 이용하여 정렬하는 방법 외에도 DECODE(), CASE WHEN~ 절을 사용하여 특정 값을 기준으로 한 정렬 우선순위를 지정하는 것이 가능하다!

 

특정 값을 직접 지정하여 정렬(공통)

= 혹은 LIKE 등을 이용하여 특정 값을 직접 지정하여 ORDER BY 절에서 사용할 수 있다.

아래 코드를 예로 들면, 나머지 -> 조건2 -> 조건1 순으로 정렬이 이루어진다.

order by CITY_NAME LIKE '서%', CITY_NAME LIKE '광%'
-- 여러 조건식 지정 가능, 나머지 -> 조건2 -> 조건1 순으로 정렬

 

조건함수를 사용하여 특정값 기준 정렬

Tibero / Oracle DB

oracle에서는 CASE WHEN~ 절과 DECODE() 함수를 사용하여 커스텀 정렬이 가능하다.

아래처럼 쿼리문을 작성하면 '기타' 값을 갖는 데이터는 가장 마지막으로 정렬된다.

ORDER BY CASE WHEN CNSL_DEP_NM = '기타' THEN 2 ELSE 1 END
-- 혹은
ORDER BY DECODE(CNSL_DEP_NM, '기타', 2, 1)

 

MySQL

FIELD() 사용 시, 명시한 값 순서대로 우선순위가 결정되어 데이터가 정렬된다.

예를 들어, 값1은 값2보다 우선순위가 높으므로 값1 -> 값2 순서대로 정렬된다.

 

값 목록에 없는 데이터들은 값 목록에 있는 데이터보다 높은 우선순위를 갖되, 그 안에서는 정렬 기준이 없으므로 보통 테이블에 입력된 순서대로 정렬된다. (나머지 -> 값1 -> 값2)

 

ex) CITY_NAME = ['서울', '대전', '대구', '부산', '울산']이고 ORDER BY FIELD(CITY_NAME, '울산', '서울')인 경우

→ '대전', '대구', '부산', '울산', '서울' 순으로 정렬

ORDER BY CASE WHEN CNSL_DEP_NM = '기타' THEN 2 ELSE 1 END
-- 혹은
FIELD(필드명, 값1, 값2, ...)

 

PostgreSQL

postgreSQL에서는 DECODE() 함수는 사용할 수 없지만 CASE WHEN ~ 절을 사용할 수 있으므로 해당 방식으로 커스텀 정렬이 가능하다.

 

혹은 array(배열)을 활용하여 커스텀 정렬이 가능하다.

아래 예시를 예로 들면, ARRAY[]에 입력한 값 순서대로 우선순위를 갖는 건 위의 다른 DB들과 동일하다.

하지만 postgreSQL은 ARRAY[]에 지정하지 않은 나머지 값은 ARRAY[] 값 이후에 정렬된다는 차이점이 있다.

(값1 -> 값2 -> 나머지 순)

 

그리고 주의점!

array_position() 사용 시, 기준 컬럼명인 두 번째 파라미터 뒤에 꼭 ::text를 붙여줘야 한다.

ORDER BY CASE WHEN CNSL_DEP_NM = '기타' THEN 2 ELSE 1 END
-- 혹은
ORDER BY array_position(ARRAY['공모','행사','공지'], category::text)