티스토리 뷰

신입일 때 오름차순, 내림차순 혹은 ASC, DESC가 많이 헷갈렸다. 지금도 주니어들을 보면 가끔 반대로 말하고 쓰기도 하는데, 이에 따른 노하우를 정리해보려고 한다.

의미

오름차순(ASC)은 1, 2, 3, 4, 5 이런 식으로 숫자 혹은 날짜가 증가하는 것을 의미하며,

내림차순(DESC)은 5, 4, 3, 2, 1 이런 식으로 숫자 혹은 날짜가 감소하는 것을 의미한다.

의미는 아는데 실무를 보다 보면 헷갈릴 때가 왕왕 있다.

노하우 (한글)

이럴 때는 계단을 생각하면 이해가 쉽다.

계단을 오른다고 상상해보자. 1층에서부터 올라가다 보면 1층 2층 3층 4층 5층. 오르다의 오름차순.

이번에는 반대로 내려간다고 생각해보자. 5층부터 내려가다 보면 5층 4층 3층 2층 1층. 내려간다의 내림차순.

노하우 (영어)

오름차순과 내림차순은 이 정도로만 기억해도 실무에서 헷갈리지 않고 쓸 수 있다. 문제는 개발할 때 ASC랑 DESC이다. 영어 고수라면 문제가 없지만 우리는 헷갈린다.

하지만 이것도 같은 방법으로 계단으로 대입이 가능하다.

A는 D보다 작다. A에서 D로 올라간다. A, B, C, D. 그래서 A로 시작하는 ASC는 오름차순.

D는 A보다 크다. D에서 A로 내려간다. D, C, B, A. 그래서 D로 시작하는 DESC는 내림차순.

별것 아닌 것 같지만 이렇게 한번 들어두면 절대 잊어버리지 않는다.


덤: 정렬에서 실제로 사고가 나는 지점들

의미를 아는 것과 실무에서 안 틀리는 건 또 다른 문제다. 정렬 때문에 실제로 터지는 케이스들을 정리해둔다.

1. 기본값은 ASC다

ORDER BY created_at         -- ASC (오래된 것부터)
ORDER BY created_at ASC     -- 위와 동일

생략하면 오름차순이다. "최신순"을 의도하고 ORDER BY created_at 만 쓰면 가장 오래된 글이 맨 위에 온다. 헷갈리지 않으려면 항상 명시하는 습관이 낫다.

2. 여러 컬럼 정렬 시 방향은 각각 지정해야 한다

-- 의도: 카테고리 오름차순, 날짜 내림차순
ORDER BY category_id, created_at DESC   -- category_id는 ASC (맞음)

-- 흔한 실수: 둘 다 DESC로 하려 했는데
ORDER BY category_id, created_at DESC   -- category_id는 여전히 ASC

-- 올바른 형태
ORDER BY category_id DESC, created_at DESC

DESC바로 앞 컬럼 하나에만 적용된다. 뒤에 한 번 붙였다고 앞의 것까지 적용되지 않는다.

3. NULL의 위치가 DB마다 다르다

  • MySQL — ASC에서 NULL이 맨 앞, DESC에서 맨 뒤
  • PostgreSQL — ASC에서 NULL이 맨 뒤, DESC에서 맨 앞 (MySQL과 반대)
  • Oracle — 기본은 ASC에서 NULL이 맨 뒤

DB를 이전하면 정렬 결과가 미묘하게 달라지는 원인이 이것이다. 명시적으로 지정할 수 있다.

-- PostgreSQL / Oracle
ORDER BY updated_at DESC NULLS LAST

-- MySQL (NULLS LAST 문법이 없어서 우회)
ORDER BY updated_at IS NULL, updated_at DESC

4. 문자열로 저장된 숫자는 사전순으로 정렬된다

-- version 컬럼이 VARCHAR인 경우
'1', '10', '2', '20', '3'   -- 이렇게 정렬된다

숫자처럼 보이지만 문자열이면 첫 글자부터 비교한다. 102보다 앞에 오는 이유다. 정렬이 필요한 숫자는 처음부터 숫자 타입으로 저장해야 한다.

5. 정렬 키가 중복되면 순서가 보장되지 않는다

이게 실무에서 가장 골치 아픈 케이스다. ORDER BY created_at DESC 인데 같은 초에 생성된 행이 여럿이면, 그들 사이의 순서는 미정이다. 페이지네이션과 만나면 같은 글이 두 페이지에 나오거나 아예 안 나오는 현상이 생긴다.

-- 항상 유니크 컬럼을 마지막에 붙인다
ORDER BY created_at DESC, id DESC

6. 한글 정렬은 콜레이션에 달렸다

한글 이름을 가나다순으로 정렬하려면 컬럼의 콜레이션이 utf8mb4_unicode_ci 또는 utf8mb4_general_ci 여야 한다. utf8mb4_bin 이면 코드포인트 순서로 정렬돼서 우리가 기대하는 가나다순이 안 나온다.

정리

  • 계단을 떠올린다. 올라가면 오름차순(ASC), 내려가면 내림차순(DESC)
  • A→D로 올라가니 ASC, D→A로 내려가니 DESC
  • 기본값은 ASC다. 헷갈리지 않으려면 항상 명시
  • DESC는 바로 앞 컬럼에만 적용된다
  • NULL 위치는 MySQL과 PostgreSQL이 반대
  • 정렬 키 마지막에는 유니크 컬럼을 붙인다

이 블로그를 본 사람들은 평생 잊지 않기 때문에 다시 이 글을 찾아보지 않을 것이다.

댓글


최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday