본문 바로가기
Java.DB/SQL

[Oracle/SQL] ORDER BY

by 개발자 아구몬 2022. 10. 26.

ORDER BY


-- 기본 형식 : SELECT [필드명] FROM 테이블명 ORDER BY 필드 [ASC | DESC]
SELECT name FROM member ORDER BY age; -- age 오름차순대로 이름을 출력
SELECT name FROM member ORDER BY age DESC; -- age 내림차순대로 이름을 출력
SELECT name FROM member ORDER BY age, toeic DESC; -- 나이 오름차순, 같다면 토익 내림차순

 

SELECT 명령에 별 지정이 없을 경우, 레코드의 출력 순서는 DBMS의 디폴트 순서를 따르지만, 이 경우에도 명확하게 순서가 보장되지는 않는다. 사실, 관계형 DB에서 레코드의 물리적 순서는 큰 의미가 없다. 물리적 순서가 중요한 것은 이를 읽는 사람의 입장이며, 이러한 경우 순서를 지정하기 위한 키워드가 바로 ORDER BY 이다.

ORDER BY문 뒤에는 ASC(오름차순) 혹은 DESC(내림차순) 키워드를 넣어 정렬 기준을 지정할 수 있다. 디폴트값은 ASC이며, 생략이 가능하다. 또한 쉼표로 구분하여 여러개의 정렬기준을 둘 수 있다. 먼저 선언한 정렬기준이 적용되며, 이 기준이 같다면 이후의 정렬기준이 적용된다.

 

SELECT name FROM member ORDER BY 1; -- name이 첫번째 필드이므로 name으로 정렬
SELECT name FROM member ORDER BY age * 2; -- 수식도 가능

 

ORDER BY의 기준은 일반적으로 필드명으로 하지만, 필드의 순서값으로 지정할 수 있다. 필드 순서값은 테이블 생성시에 등록된 순서대로이다. 직관적이지는 않지만 동적 테이블 생성 등으로 인해 필드명이 가변적일 때 등 유용하게 사용되는 경우가 있다.

또한 테이블에 직접적으로 존재하지 않는 계산된 값도 정렬 기준으로 사용할 수 있다.

-- 기본 형식 : SELECT [필드명] FROM 테이블명 WHERE 조건 ORDER BY 필드 [ASC | DESC]
SELECT * FROM member WHERE region = '서울' ORDER BY age;

 

ORDER BY는 WHERE절과 동시에 사용할 수 있다. 단, ORDER BY절은 반드시 WHERE 절 뒤에 와야한다.

 

DISTINCT


SELECT DISTINCT region FROM member; -- 중복된 도시를 제거하고 하나씩만 출

 

중복된 값을 제거하여 한번만 출력할때는 DISTINCT 키워드를 사용한다. DISTINCT의 반대 키워드는 ALL이지만, 디폴트값이라 실제론 거의 사용하지 않는다. DISTINCT와 동의어인 UNIQUE를 쓰는 DBMS도 있지만 이는 SQL 표준이 아니며, 특히 SQL Server은 지원하지 않는다.

Oracle : 의사컬럼

SELECT name, rowid, rownum FROM member;
SELECT * FROM member WHERE rownum <=4 ; -- 4번째 이하의 멤버 출력

 

의사 컬럼(Pseudo Column) 은 Oracle에서만 제공되는, 실제 테이블에는 없으나 인위적으로 추가한 가짜 컬럼이다. 오라클은 필드 목록에 없더라도 항상 내부적인 식별자가 저장되는 rownum과 순서대로 붙인 일련번호인 rowid 열을 생성하며, 이를 언제든지 참조할 수 있다.

다만 ORDER BY 등으로 “정렬된 결과셋”에서 rownum을 이용하기 위해서는 이후에 배울 서브쿼리를 이용해야하는 등, 불편한 사항이 많다.

SQL Server : TOP

SELECT TOP 4 * FROM member ORDER BY age DESC; -- 상위 4개
SELECT TOP 20 PERCENT * FROM member ORDER BY age; -- 상위 20%
SELECT TOP 20 PERCENT WITH TIES * FROM member ORDER BY Score DESC; -- 동점자 포함 

 

SQL Server는 TOP n 구문으로 행수를 제어한다. SELECT 키워드와 필드 목록 사이에 출력할 레코드 개수와 함께 입력할 수 있으며, Oracle의 의사컬럼과는 달리 ORDER BY 등으로 정렬된 결과 셋에도 깔끔하게 적용이 가능하다.

TOP n PERCENT 구문으로 비율을 지정할 수도 있다. 비율에서 동점자 문제가 발생한다면, WITH TIES 옵션을 통해 동점자를 포함할 수 있다. 동점자는 정렬된 경우에만 나타날 수 있으므로, 이 옵션은 ORDER BY로 정렬된 구문에서만 입력이 가능하다.

MySQL : LIMIT

-- 형식 : SELECT ... LIMIT [건너뛸 개수], 총개수
SELECT * FROM member ORDER BY age DESC LIMIT 4; -- 상위 4개
SELECT * FROM member ORDER BY age DESC LIMIT 2,3; -- 2개 건너뛰고 상위 3개
SELECT * FROM member ORDER BY age DESC LIMIT 3 OFFSET 2; -- 위와 같음

 

MySQL 류는 LIMIT 문법을 지원하며, TOP과 비슷하지만 SELECT문의 맨 뒤에 둔다.

쉼표나 OFFSET 구문으로 일부분을 건너뛸 수도 있다.

OFFSET FETCH

DBMS마다 결과값을 특정하는 문법이 달라 많은 불편사항이 발생하여, OFFSET FETCH라는 구문이 새롭게 SQL 표준에 편입되었다. 레코드의 일부분을 특정하려면 순서를 지정해야 하므로, 사용하기 위해선 ORDER BY문이 반드시 있어야 한다. 즉 OFFSET FETCH는 ORDER BY의 옵션 구문이다.

 

-- 기본형식 : ORDER BY 기준필드 OFFSET 건너뛸 행수 ROW(S) FETCH NEXT 출력할행수 ROWS ONLY
SELECT * FROM member ORDER BY age DESC OFFSET 2 FETCH NEXT 4 ROWS ONLY; -- 2개 건너뛰고 4개

 

위 구문에서 ROWROWS라고 써도 되며, NEXTFIRST라고 써도 된다.

  • Oracle : 정렬하지 않을 시 ORDER BY 생략이 가능하며, 건너뛰지 않을떄 OFFSET 0 ROWS도 생략가능
  • SQL Server : 위의 두 구문을 생략할 수 없다.
  • MySQL : 아직 이 구문을 지원하지 않으나, LIMIT 구문이 같은 역할을 한다.

'Java.DB > SQL' 카테고리의 다른 글

[SQL] WHERE  (0) 2022.10.26
[SQL] SELECT  (0) 2022.10.21