티스토리 뷰
쿼리를 조회하면서 특정 칼럼의 특정 값을 최우선으로 정렬하고 나머지 정렬을 하고 싶을 때가 있다.
예를 들어 공지사항에서 최상단 5개를 고정으로 박아놓고 나머지를 날짜순으로 정렬한다 던 지..
기획의도에 따라서 어떠한 값을 최우선으로 보이게하고 그다음부터 나머지를 보여지게 한다던지.. 이런 경우이다.
샘플 공지사항 테이블을 만들어서 테스트
예제
WITH TBL_NOTICE AS (
SELECT 1 AS ID
, '제목1' AS TITLE
, '내용1' AS CONTENT
, 'N' AS FIX_YN
, SYSDATE AS REG_DATE
FROM DUAL
UNION ALL
SELECT 2 AS ID
, '제목2' AS TITLE
, '내용2' AS CONTENT
, 'N' AS FIX_YN
, SYSDATE - 10 AS REG_DATE
FROM DUAL
UNION ALL
SELECT 3 AS ID
, '제목3' AS TITLE
, '내용3' AS CONTENT
, 'N' AS FIX_YN
, SYSDATE - 1 AS REG_DATE
FROM DUAL
UNION ALL
SELECT 4 AS ID
, '제목4' AS TITLE
, '내용4' AS CONTENT
, 'Y' AS FIX_YN
, SYSDATE - 2 AS REG_DATE
FROM DUAL
UNION ALL
SELECT 5 AS ID
, '제목5' AS TITLE
, '내용5' AS CONTENT
, 'Y' AS FIX_YN
, SYSDATE - 3 AS REG_DATE
FROM DUAL
)
SELECT *
FROM TBL_NOTICE;
여기에서 특정 칼럼 FIX_YN 이 Y인 것을 최상단으로 조회하고 그 다음부터 나머지를 조회하고 싶을 때 ORDER BY 절에 CASE WHEN 구문을 작성하면 된다.
WITH TBL_NOTICE AS (
SELECT 1 AS ID
, '제목1' AS TITLE
, '내용1' AS CONTENT
, 'N' AS FIX_YN
, SYSDATE AS REG_DATE
FROM DUAL
UNION ALL
SELECT 2 AS ID
, '제목2' AS TITLE
, '내용2' AS CONTENT
, 'N' AS FIX_YN
, SYSDATE - 10 AS REG_DATE
FROM DUAL
UNION ALL
SELECT 3 AS ID
, '제목3' AS TITLE
, '내용3' AS CONTENT
, 'N' AS FIX_YN
, SYSDATE - 1 AS REG_DATE
FROM DUAL
UNION ALL
SELECT 4 AS ID
, '제목4' AS TITLE
, '내용4' AS CONTENT
, 'Y' AS FIX_YN
, SYSDATE - 2 AS REG_DATE
FROM DUAL
UNION ALL
SELECT 5 AS ID
, '제목5' AS TITLE
, '내용5' AS CONTENT
, 'Y' AS FIX_YN
, SYSDATE - 3 AS REG_DATE
FROM DUAL
)
SELECT *
FROM TBL_NOTICE
ORDER BY CASE WHEN FIX_YN = 'Y' THEN 0 END, REG_DATE DESC
FIX_YN 값이 Y 인 값이 있으면 가장 먼저 정렬하고 그다음에 날짜순으로 정렬을 수행한다.
여기까지 이해하는데 큰 문제는 없었는데 내가 좀 이해하는데 시간이 좀 걸린 곳은
ORDER BY CASE WHEN 칼럼 = '특정 값' THEN 0 이 부분이었다.
ORDER BY 절에는 칼럼명을 포함해서 1,2,3 같은 숫자가 들어가는 걸로 알고 있었다. 숫자 1,2,3은 SELECT 절의 칼럼 순번이다.
SELECT 컬럼명
FROM 테이블명
WHERE 조건식
GROUP BY 컬럼명
ORDER BY 컬럼명1 [ASC|DESC], 컬럼명2 [ASC|DESC], 컬럼명3 [ASC|DESC] ...
그런데 내 머리로는 ORDER BY 0 하면 안 될 텐데.. 하는 생각이 자꾸 스며들었다. 실제로 SELECT 쿼리를 수행할 때 ORDER BY 0을 수행하면 쿼리 오류가 났다. 아 그럼 뭐지.. 하면서 계속 찾다가 그냥 이렇게 이해하기로 했다.
ORDER BY 절에 DECODE나 CASE WHEN 문을 써서 정렬을 할 때는 특정 값의 순서를 나타내기 위한 0~n까지의 값일 뿐이다.
0~n 까지니까 0이 1순위고 그다음 1,2,3... 이 순서이다. 꼭 0부터 안 해도 상관없고 100부터 해도 된다. 대신 100보다 아래 값이 있으면
그게 먼저 우선순위로 정렬이 된다.
WITH TBL_NOTICE AS (
SELECT 1 AS ID
, '제목1' AS TITLE
, '내용1' AS CONTENT
, 'N' AS FIX_YN
, SYSDATE AS REG_DATE
FROM DUAL
UNION ALL
SELECT 2 AS ID
, '제목2' AS TITLE
, '내용2' AS CONTENT
, 'N' AS FIX_YN
, SYSDATE - 10 AS REG_DATE
FROM DUAL
UNION ALL
SELECT 3 AS ID
, '제목3' AS TITLE
, '내용3' AS CONTENT
, 'N' AS FIX_YN
, SYSDATE - 1 AS REG_DATE
FROM DUAL
UNION ALL
SELECT 4 AS ID
, '제목4' AS TITLE
, '내용4' AS CONTENT
, 'Y' AS FIX_YN
, SYSDATE - 2 AS REG_DATE
FROM DUAL
UNION ALL
SELECT 5 AS ID
, '제목5' AS TITLE
, '내용5' AS CONTENT
, 'Y' AS FIX_YN
, SYSDATE - 3 AS REG_DATE
FROM DUAL
)
SELECT *
FROM TBL_NOTICE
ORDER BY CASE
WHEN TITLE = '제목2' THEN 0
WHEN TITLE = '제목3' THEN 1 END;
제목2를 첫 번째 우선순위로 두고 그다음으로 제목3을 정렬하겠다는 의미이다. 저걸 1,2,3,4... 의 순서로 해도 상관이 없다.
참고
https://javappo.tistory.com/130
https://www.haguangho.com/80?category=755040
https://leeyebin.tistory.com/43
https://20140501.tistory.com/111
- Total
- Today
- Yesterday
- LocalDateTime
- Linux
- Bash tab
- Spring Security
- window
- springboot
- jQuery
- 북리뷰
- rocky
- elasticsearch
- intellij
- LocalDate
- localtime
- docker
- input
- maven
- JavaScript
- 베리 심플
- Java
- Spring
- Github Status
- mybatis config
- oracle
- svn
- 오라클
- k8s
- config-location
- Mac
- Kotlin
- mybatis
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |