모던지 / SQL 개발자 / SQL 기본 및 활용 5강. ORDER BY 절

SQL 기본 및 활용 5강. ORDER BY 절

정렬을 지시하지 않은 결과의 순서는 우연입니다. 어제까지 잘 나오던 순서가 오늘 바뀌어도 데이터베이스는 약속을 어긴 것이 아닙니다.

풀고 시작

문제 1. ORDER BY 절에서 사용할 수 없는 것은?
집합 연산자로 여러 질의를 묶으면 정렬은 맨 마지막에 한 번만 쓸 수 있습니다. 별칭과 컬럼 순번은 ORDER BY가 SELECT 다음에 처리되기 때문에 모두 사용할 수 있고, 결과에 표시하지 않은 컬럼으로도 정렬할 수 있습니다.

가장 마지막에 처리되는 절

1강에서 본 처리 순서의 맨 끝이 ORDER BY입니다. FROM으로 대상을 정하고, 조건으로 걸러 내고, 묶고, 열을 고른 다음에야 줄을 세웁니다. 이 위치 때문에 ORDER BY만 누리는 특권이 두 개 있습니다.

첫째, SELECT 절에서 붙인 별칭을 쓸 수 있습니다. 별칭은 SELECT에서 생기는데 ORDER BY는 그다음이니 이미 알고 있죠. 둘째, SELECT 절에 나열한 순서를 숫자로 가리킬 수 있습니다. 두 번째 컬럼으로 정렬하라는 지시를 숫자 2로 쓸 수 있습니다. 다만 이 방식은 SELECT 절의 컬럼 순서를 바꾸면 정렬 기준이 조용히 따라 바뀌므로, 읽기와 유지보수 면에서는 컬럼명이나 별칭을 쓰는 편이 낫습니다.

정렬 방향은 오름차순이 기본값입니다. 아무것도 쓰지 않으면 작은 값부터 나오고, 큰 값부터 원하면 내림차순을 지정합니다. 여러 컬럼을 나열하면 앞의 컬럼이 같을 때만 뒤의 컬럼이 작동하고, 방향은 컬럼마다 따로 지정할 수 있습니다.

NULL은 어디에 서는가

정렬에서 값이 없는 행이 어디로 가는지는 제품마다 다릅니다. 어떤 제품은 오름차순에서 NULL을 가장 뒤에 두고, 어떤 제품은 가장 앞에 둡니다. 그래서 표준 SQL에는 NULL의 위치를 직접 지정하는 구문이 있고, 대부분의 제품이 이를 지원합니다. NULLS FIRST와 NULLS LAST가 그것입니다.

시험에서는 특정 제품의 기본 동작을 외우게 하기보다 기본 동작이 제품에 따라 갈린다는 사실위치를 명시할 수 있다는 사실을 확인합니다. 실무에서는 명시해 두는 편이 안전합니다. 데이터베이스를 옮기는 순간 보고서의 첫 줄이 마지막 줄로 내려앉는 일을 겪지 않으려면요.

정렬 대상은 결과에 없어도 됩니다

ORDER BY의 재밌는 성질 하나는 결과에 표시하지 않는 컬럼으로도 정렬할 수 있다는 점입니다. 사원명만 뽑으면서 입사일 순으로 줄을 세워도 됩니다. 입사일은 화면에 나오지 않지만 순서에는 반영되죠.

여기에 예외가 있습니다. DISTINCT를 쓰거나 집합 연산자로 묶은 경우에는 결과에 없는 컬럼으로 정렬할 수 없습니다. DISTINCT는 중복을 없애면서 원래 행의 정체를 지워 버리기 때문입니다. 같은 이름이 두 번 있었는데 하나로 합쳤다면, 그 하나의 입사일이 무엇이어야 할지 정할 수 없습니다.

GROUP BY를 쓴 경우에도 마찬가지로 그룹 기준 컬럼과 집계 함수 결과로만 정렬할 수 있습니다. 4강에서 SELECT 절에 걸렸던 규칙이 ORDER BY에도 그대로 적용되는 셈이죠.

정렬은 값이 비싼 작업입니다

정렬은 데이터를 모두 모아 놓고 순서를 매기는 작업이라 메모리와 시간을 씁니다. 정렬할 양이 메모리에 담기지 않으면 디스크를 쓰게 되고 그때부터 눈에 띄게 느려집니다.

그래서 실무의 요령이 몇 가지 있습니다. 정렬 기준 컬럼에 인덱스가 있으면 데이터베이스가 인덱스를 순서대로 읽어 정렬 작업 자체를 건너뛸 수 있습니다. 정렬한 결과의 앞부분만 필요하다면 12강에서 볼 Top N 구문으로 범위를 줄여 주는 편이 낫습니다. 그리고 화면에 필요하지 않은 정렬은 아예 빼는 것이 가장 확실한 개선입니다. 목록 화면마다 습관적으로 붙은 정렬 하나가 전체 응답 시간의 절반을 먹고 있는 경우가 드물지 않습니다.

한 가지 더, 문자로 저장된 숫자를 정렬하면 사전 순으로 정렬됩니다. 10이 2보다 앞에 오죠. 자료형이 문자인데 숫자처럼 보이는 컬럼을 정렬할 때는 숫자로 변환해 정렬해야 하고, 그 변환 때문에 인덱스를 못 쓰게 되는 대가를 함께 치릅니다. 애초에 숫자로 저장했어야 하는 값이라는 신호이기도 합니다.

다음 강부터 조인으로 들어갑니다. 2과목의 문항 수가 가장 몰려 있는 구간이니 천천히 보셔도 좋습니다.

인출 문제

문제 1. ORDER BY 절이 SELECT 절의 별칭을 사용할 수 있는 이유는?
처리 순서에서 SELECT 다음에 오는 절만 별칭을 알아볼 수 있고, 그 절은 ORDER BY입니다. WHERE와 GROUP BY와 HAVING은 모두 SELECT보다 먼저 처리되므로 별칭을 인식하지 못합니다.
문제 2. 정렬에서 값이 없는 행의 위치에 대한 설명으로 옳은 것은?
기본 동작이 제품마다 갈리기 때문에 NULLS FIRST나 NULLS LAST로 명시하는 구문이 있습니다. 값이 없는 행이 결과에서 빠지는 것은 아닙니다.
문제 3. DISTINCT를 사용한 SELECT 문에서 결과에 표시하지 않은 컬럼으로 정렬할 수 없는 이유는?
중복 제거로 여러 행이 하나로 합쳐지면 그 행이 원래 어느 행이었는지가 사라집니다. 그래서 결과에 남지 않은 컬럼의 값이 무엇이어야 할지 결정할 수 없습니다.
문제 4. 여러 컬럼을 ORDER BY에 나열했을 때의 동작으로 옳은 것은?
앞에서부터 우선하며, 앞이 같을 때만 뒤가 작동합니다. 정렬 방향은 컬럼마다 따로 지정할 수 있어 하나는 오름차순, 하나는 내림차순으로 섞어 쓸 수 있습니다.

더 풀기

출제기준의 세세항목을 따라 이 강의 범위에서 새로 낸 문제입니다. 모의고사도 여기에서 뽑습니다.

묶음 1

문제 1. ORDER BY 절이 논리적 처리 순서에서 가장 마지막인 이유로 가장 알맞은 것은?
정렬은 결과 집합을 만든 다음에 하는 일입니다. 그래서 SELECT 절의 별칭도 쓸 수 있습니다.
문제 2. ORDER BY 절에서 SELECT 절의 별칭을 쓸 수 있는 이유는?
처리 순서로 설명됩니다. 반대로 WHERE는 SELECT보다 먼저 처리되어 별칭을 쓸 수 없습니다.
문제 3. ORDER BY의 기본 정렬 방향은?
방향을 적지 않으면 오름차순입니다. 내림차순은 DESC를 명시해야 합니다.
문제 4. 정렬 기준을 여러 개 지정했을 때의 동작으로 옳은 것은?
앞의 기준이 우선이고 동점일 때 뒤의 기준이 순서를 정합니다. 이것을 알아야 예상한 순서를 얻을 수 있습니다.
문제 5. 여러 정렬 기준 각각에 다른 방향을 지정할 수 있나요?
부서는 오름차순으로, 급여는 내림차순으로 정렬하는 식이 가능합니다. 방향은 기준마다 독립적입니다.
문제 6. ORDER BY 절에 컬럼 이름 대신 숫자를 쓰면 무엇을 뜻하나요?
숫자는 SELECT 절의 위치를 가리킵니다. 다만 SELECT 항목이 바뀌면 정렬 기준이 조용히 달라지므로 실무에서는 권하지 않습니다.
문제 7. ORDER BY 절에 위치 번호를 쓰는 것을 권하지 않는 이유로 가장 알맞은 것은?
컬럼 하나를 앞에 끼워 넣는 순간 정렬이 달라지고 오류도 나지 않습니다. 이런 변화는 발견하기 어렵습니다.
문제 8. 오라클 계열 제품에서 오름차순 정렬 시 NULL은 어디에 오나요?
제품마다 기본이 다릅니다. 오라클은 오름차순에서 NULL을 마지막에 두고, 반대 규칙을 가진 제품도 있습니다.
문제 9. NULL의 위치를 명시적으로 지정하려면 어떤 표현을 쓰나요?
이 표현으로 제품 기본값에 상관없이 위치를 고정할 수 있습니다. 이식성을 생각하면 명시하는 편이 안전합니다.
문제 10. 급여가 백, NULL, 삼백인 세 행을 급여 오름차순으로 정렬하고 NULL을 앞에 두도록 지정하면 순서는?
NULL을 먼저 두라고 지정했으므로 NULL이 맨 앞이고 나머지는 오름차순으로 백과 삼백입니다.

묶음 2

문제 1. 정렬 기준으로 쓴 컬럼이 SELECT 절에 없어도 되나요?
화면에 보이지 않는 컬럼으로도 정렬할 수 있습니다. 다만 집합 연산자를 쓴 질의에서는 제약이 생깁니다.
문제 2. 집합 연산자를 사용한 질의에서 ORDER BY를 쓸 때의 제약으로 옳은 것은?
집합 연산은 결과를 합친 뒤 전체를 정렬합니다. 그래서 정렬 기준도 최종 결과에 있는 컬럼이어야 합니다.
문제 3. DISTINCT를 쓴 질의에서 SELECT 절에 없는 컬럼으로 정렬하려 하면 어떻게 되나요?
여러 행이 하나로 합쳐졌는데 그중 어느 값으로 정렬할지 정할 수 없습니다. 그래서 문법으로 막힙니다.
문제 4. 정렬을 명시하지 않았는데 결과가 정렬되어 보이는 이유로 가장 알맞은 것은?
실행 계획이 바뀌면 순서도 바뀝니다. 우연을 규칙으로 믿으면 어느 날 조용히 깨집니다.
문제 5. 정렬 작업이 비싼 이유로 가장 알맞은 것은?
정렬은 전체를 봐야 끝납니다. 그래서 대상이 커지면 메모리를 넘어가고 그때부터 비용이 크게 뜁니다.
문제 6. 정렬 비용을 줄이는 방법으로 가장 알맞은 것은?
인덱스는 이미 정렬된 구조입니다. 그 순서를 그대로 쓸 수 있으면 정렬 작업 자체를 건너뛸 수 있습니다.
문제 7. 부서 오름차순, 급여 내림차순으로 정렬할 때 그 순서를 그대로 활용할 수 있는 인덱스는?
정렬 순서와 인덱스의 컬럼 순서와 방향이 맞아야 그대로 읽을 수 있습니다. 방향이 다르면 다시 정렬해야 하는 경우가 생깁니다.
문제 8. 한글 데이터를 정렬할 때 결과가 시스템마다 다를 수 있는 이유는?
어떤 규칙으로 문자를 비교하느냐가 정렬 결과를 정합니다. 이식할 때는 이 설정을 함께 확인해야 합니다.
문제 9. 대소문자를 구분하지 않고 이름순으로 정렬하려면?
모두 대문자나 소문자로 바꾼 값으로 정렬하면 됩니다. 다만 그러면 그 컬럼의 인덱스를 그대로 쓰기는 어려워집니다.
문제 10. 숫자가 문자형으로 저장된 컬럼을 숫자 크기대로 정렬하려면?
문자 정렬은 사전 순이라 십이 구보다 앞에 옵니다. 숫자로 바꾸어 비교해야 크기 순이 됩니다.

묶음 3

문제 1. 급여가 백, 이백, 이백, 삼백인 네 행을 급여 내림차순으로 정렬하면 첫 행의 급여는?
내림차순이므로 가장 큰 삼백이 먼저 옵니다.
문제 2. 같은 데이터에서 급여가 같은 두 행의 상대 순서는 어떻게 정해지나요?
동점의 순서를 고정하려면 정렬 기준을 하나 더 주어야 합니다. 그러지 않으면 실행할 때마다 달라질 수 있습니다.
문제 3. 페이지를 나누어 조회할 때 정렬 기준에 동점이 많으면 생기는 문제로 가장 알맞은 것은?
페이지 나누기는 순서가 안정적이어야 성립합니다. 동점을 가르는 유일한 기준을 마지막에 하나 넣어 주는 것이 안전합니다.
문제 4. 정렬 기준에 유일성을 가진 컬럼을 마지막에 추가하는 이유는?
순서가 결정적이어야 페이지 나누기와 결과 비교가 신뢰할 만해집니다.
문제 5. ORDER BY 절에 표현식을 쓸 수 있나요?
급여에 수당을 더한 값이나 이름의 길이로도 정렬할 수 있습니다. 다만 인덱스를 그대로 쓰기는 어려워집니다.
문제 6. 특정 값을 항상 맨 위에 오도록 정렬하려면 어떤 방법이 가장 알맞은가요?
원하는 값에 작은 수를 주고 나머지에 큰 수를 주면 그 값이 먼저 옵니다. 그다음 기준으로 나머지 순서를 정합니다.
문제 7. 정렬 결과의 상위 몇 건만 필요할 때 성능상 유리한 접근으로 가장 알맞은 것은?
인덱스 순서가 정렬 순서와 같으면 앞에서 몇 건만 읽고 끝낼 수 있습니다. 전체 정렬은 필요 없는 일을 다 하는 셈입니다.
문제 8. 다음 중 ORDER BY에 대한 설명으로 옳지 않은 것은?
그룹으로 묶은 결과도 얼마든지 정렬할 수 있습니다. 오히려 그룹 결과는 순서가 보장되지 않아 정렬이 더 필요합니다.
문제 9. 정렬 없이 조회한 결과를 그대로 페이지로 나누어 보여 주면 생기는 문제는?
순서가 없는 집합을 잘라 내는 것은 뜻이 없습니다. 페이지 나누기는 정렬을 전제로 합니다.
문제 10. 정렬 기준 컬럼에 NULL이 많을 때 확인해야 할 것으로 가장 알맞은 것은?
값이 없는 행을 먼저 보여 줄지 나중에 보여 줄지는 업무가 정합니다. 제품 기본값에 맡기면 이식할 때 결과가 바뀝니다.

이전: 4강 집계 함수와 GROUP BY · 다음: 6강 조인의 원리

모던지 · 궁금하면 모던지 GitHub · 2026-09-10