걸음마부터 달리기
DB- ORDER BY 본문
ORDER BY 절은 SQL 문장으로 조회된 데이터들을 다양한 목적에 맞게 특정 칼럼을 기준으로 정렬하여 출력하는데 사용한다. ORDER BY 절에 칼럼(Column) 명 대신에 SELECT 절에서 사용한 ALIAS 명이나 칼럼 순서를 나타내는 정수도 사용 가능하다. 그리고 별도로 정렬 방식을 지정하지 않으면 기본적으로 오름 차순이 적용되며, SQL 문장의 제일 마지막에 위치한다. ORDER BY 를 기입하지 않으면 튜플은 서로 순서가 없는게 맞다. 하지만 ORDER BY 칼럼명 까지만 기입하여 ORDER BY를 실행하면 뒤에 DESC 냐 ASC냐 상관없이 그냥 오름차순 정리한다는 거다.
SELECT 칼럼명 [ALIAS명]
FROM 테이블명
[WHERE 조건식]
[GROUP BY 칼럼(Column)이나 표현식]
[HAVING 그룹조건식]
[ORDER BY 칼럼(Column)이나 표현 식 [ASC 또는 DESC]] ;
SELECT PLAYER_NAME 선수명, POSITION 포지션, BACK_NO 백넘버
FROM PLAYER ORDER BY 포지션 DESC;
ALIAS 사용해도 된다
날짜타입같이 데이터타입에 따라 혹은 NULL값이면 오름차순 내림차순이 애매할때가 있다.
- 날짜형 데이터 타입은 오 름차순으로 정렬했을 경우 날짜 값이 가장 빠른 값이 먼저 출력된다. 예를 들어 ‘01-JAN-2012’는 ‘01-SEP-2012’보다 먼저 출력된다.
- Oracle에서는 NULL 값을 가장 큰 값으로 간주하여 오름차순으로 정렬했을 경우에는 가장 마지막에, 내림차순으로 정렬했을 경우에는 가장 먼저 위치한다.
- 반면, SQL Server에서는 NULL 값을 가장 작은 값으로 간주하여 오름차순으로 정렬했을 경우에는 가장 먼저, 내림차순으로 정렬했을 경우에는 가장 마지막에 위치한다.
(오라클은 NULL값을 가장 크게 취급한다.)
여러 칼럼 기준으로 ORDER BY도 가능하다. 이때는 앞의 칼럼이 동일할때 뒤의 칼럼을 기준으로 정렬한다.
ORDER BY HEIGHT DESC , BACK_NO
이면 HEIGHT를 기준으로 내림차순 하는데 HEIGHT가 같을 경우 BACK_NO 를 기준으로 오름차순 한다. BACK_NO 쪽에는 생략되었기에 기본적으로 오름차순으로 수행된다.
SELECT 문장 실행 순서
SELECT 문장은 크게 6개의 절로 구성되고 수행순서는 아래와 같다.
5. SELECT 칼럼명 [ALIAS명]
1. FROM 테이블명
2. WHERE 조건식
3. GROUP BY 칼럼(Column)이나 표현식
4. HAVING 그룹조건식
6. ORDER BY 칼럼(Column)이 나 표현식;
1. 발췌 대상 테이블을 참조한다. (FROM)
2. 발췌 대상 데이터가 아닌 것은 제거한다. (WHERE)
3. 행들을 소그룹화 한다. (GROUP BY)
4. 그룹핑된 값의 조건 에 맞는 것만을 출력한다. (HAVING)
5. 데이터 값을 출력/계산한다. (SELECT)
6. 데이터를 정렬한다. (ORDER BY)
WHERE이 GROUP BY보다 먼저 수행됨을 기억하자.
또한 메모리와 관련된 작업은 전체 테이블 데이터에서 필터링을 수행하여 부분행들만 들고 있게 하는 것은 WHERE과 테이블을 메모리에 올리는 FROM밖에 없다. 나머지는 모두 메모리에 들고 있는 테이블을 기준으로 메모리에서 삭제하거나 추가하는 것 없이 단순 출력,계산일 뿐이다.
따라서 ORDER BY는 SELECT에 없는 칼럼을 기준으로 정렬을 수행해도 상관없다. WHERE이 없을 경우 FROM에만, WHERE이 있을경우 WHERE에서 메모리에 올린 데이터만 가지고 수행하면 상관없다.
DBMS가 데이터를 메모리에 올릴때 행단위로 모든 칼럼을 가져오게 된다. 여기서 WHERE로 이제 버릴거 버리고 출력하는것이다.
서브쿼리는 이야기가 좀 다른데 서브쿼리의 결과로 메모리에 올라온 데이터들은 서브쿼리 범위를 벗어나면 사용하지 못한다.
GROUP BY로 인한 메모리가 가지고 있는 테이블 구조에 대해서도 알 필요가 있다.
GROUP BY를 수행하면 GROUP BY의 기준이 되는 칼럼과 집계함수를 수행할 수 있는 숫자형 칼럼의 집계함수만 SELECT나 ORDER BY로 접근이 가능하다. 왜냐하면 그룹화 이후에는 그 그룹의 기준이 되는 칼럼 이외에는 기존의 칼럼들은 쓸모가 없기에 모든 개별 데이터를 저장하지 않기에 SELECT와 ORDER BY에서 접근하지 못한다. (잘 모르겠음)
따라서 아래의 SQL문들은 다 불가능하다.
SELECT JOB, SAL
FROM EMP
GROUP BY JOB
HAVING COUNT(*) > 0
ORDER BY SAL;
GROUP BY로 JOB과
SAL은 집계함수의 칼럼도 아니고 GROUP BY로 그룹화한 기준도 아니기에 SELECT에서 참조가 불가능하다.
TOP-N
정렬한 이후 해당 정렬로부터 최상위 N개, 최하위 N개의 데이터를 뽑아올때 아래의 과정을 거친다.
오라클에서는 정렬 후 뽑아오는게 아니라 데이터가 먼저 추출되고(랜덤으로) 그 추출된 것에서 정렬하는 것을 주의해야한다.
SELECT ENAME, SAL FROM EMP WHERE ROWNUM < 4 ORDER BY SAL DESC;
이 SQL문은 정렬하고 3개를 가져오는게 아니라 무작위로 3개를 가져오고 정렬이다.
WHERE절과 ORDER BY 의 연산 순서로 봐도 동일한 해석이다.
따라서 가장 먼저 수행되는 FROM으로 우선 테이블 자체를 정렬+필터링 해서 메모리에 올리고 거기서 3개를 뽑아오면 된다.
SELECT ENAME, SAL FROM (SELECT ENAME, SAL FROM EMP ORDER BY SAL DESC) WHERE ROWNUM < 4 ;
서브쿼리로 FROM절에서 필터링 + 정렬 하였다.