SQL Cook: 쿼리 결과 정렬

0

SQL_COOK

목록 보기
5/35
post-thumbnail

제2 장: 쿼리 결과 정렬

2장에서는 결과셋의 형태를 사용자에게 맞게 지정하는 데 중점을 둔다


2. 1 지정한 순서대로 쿼리 결과 반환

Q. 부서값이 10인 사원명∙직책∙급여를 최저부터 최고 급여순으로 표시하려고 한다

A. ORDER BY를 사용한다

select ename, job, sal
	from emp
    where deptno = 10
    order by sal asc
>>
+--------+-----------+------+
| ename  | job       | sal  |
+--------+-----------+------+
| MILLER | CLERK     | 1300 |
| CLARK  | MANAGER   | 2450 |
| KING   | PRESIDENT | 5000 |
| IREN   | TESTER    | 9000 |
+--------+-----------+------+
  • ORDER BY절에서는 결과셋의 행을 정렬할 수 있다
  • 정렬의 기본값은 ASC 즉, 오름차순이다(작은 수부터 먼저 반환한다)
  • 내림차순으로 정렬하자고 한다면 DESC를 지정해준다
  • ORDER BY 칼럼명 대신 ORDER BY select절의 칼럼순서로도 조회할 수 있다.
  • 위 예제에서 SELECT절의 대상은 'ename', 'job', 'sal'이고 순서대로 반환된다.
  • 여기서 'sal'을 정렬 기준으로 하고 싶다면 'sal'의 SELECT 목록번호 3을 넣어주면 된다.
    (좌측부터 1번)
select ename, job, sal
	from emp
    where deptno = 10
    order by 3 asc
>>
+--------+-----------+------+
| ename  | job       | sal  |
+--------+-----------+------+
| MILLER | CLERK     | 1300 |
| CLARK  | MANAGER   | 2450 |
| KING   | PRESIDENT | 5000 |
| IREN   | TESTER    | 9000 |
+--------+-----------+------+

동일하게 출력된다.


2. 2 다중 필드로 정렬하기

Q. EMP 테이블에서 DEPTNO 기준 오름차순으로 행을 정렬한 후 / 급여 내림 차순으로 정렬하려 한다

A. ORDER BY절에서 정렬 기준이 될 열을 쉼표로 구분하여 나열한다

select empno, deptno, sal, ename, job
	from emp
    order by deptno, sal desc
>>
+-------+------+--------+-----------+
| empno | sal  | ename  | job       |
+-------+------+--------+-----------+
|  7777 | 9000 | IREN   | TESTER    |
|  7839 | 5000 | KING   | PRESIDENT |
|  7782 | 2450 | CLARK  | MANAGER   |
|  7934 | 1300 | MILLER | CLERK     |
|  7902 | 3000 | FORD   | ANALYST   |
|  7788 | 3000 | SCOTT  | ANALYST   |
|  7566 | 2975 | JONES  | MANAGER   |
|  7876 | 1100 | ADAMS  | CLERK     |
|  7369 |  800 | SMITH  | CLERK     |
|  7698 | 2850 | BLAKE  | MANAGER   |
|  7499 | 1600 | ALLEN  | SALESMAN  |
|  7844 | 1500 | TURNER | SALESMAN  |
|  7521 | 1250 | WARD   | SALESMAN  |
|  7654 | 1250 | MARTIN | SALESMAN  |
|  7900 |  950 | JAMES  | CLERK     |
+-------+------+--------+-----------+
  • ORDER BY에도 우선순위가 있으며 왼쪽에서 오른쪽이다
  • 2.1에서와 마찬가지로 SELECT 목록에서 열의 위치를 숫자로 사용하여 정렬할 수 있다
    단, 이 경우 해당 숫자는 SELECT목록의 항목 수보다 크지 않아야 한다
  • 일반적으로는 SELECT목록에 없는 열로 정렬할 수도 있다
    그러나 이러한 경우에 열 이름을 명시적으로 지정해야 한다
    이렇다 하더라도 쿼리에서는 GROUP BYDISTINCT를 사용할 때, SELECT 목록에 없는 열을 기준으로 정렬할 수는 없다

2. 3 부분 문자열로 정렬하기

Q. 문자열의 특정 부분을 기준으로 쿼리 결과를 정렬하려고 한다

예를 들어, 'EMP' 테이블에서 사원명과 직급을 반환하되 'JOB'열의 마지막 두 개의 문자를 기준으로 정렬하려고 한다면?

A. SUBSTR 또는 SUBSTRING 함수를 사용한다

case: MySQL / Postgre / Oracle

  • ORDER BY절에서 SUBSTR 함수를 사용한다
select ename, job
	from emp
    order by substr(job, length(job)-1)
>>
+--------+-----------+
| ename  | job       |
+--------+-----------+
| ALLEN  | SALESMAN  |
| WARD   | SALESMAN  |
| TURNER | SALESMAN  |
| MARTIN | SALESMAN  |
| BLAKE  | MANAGER   |
| IREN   | TESTER    |
| CLARK  | MANAGER   |
| JONES  | MANAGER   |
| KING   | PRESIDENT |
| ADAMS  | CLERK     |
| SMITH  | CLERK     |
| JAMES  | CLERK     |
| MILLER | CLERK     |
| SCOTT  | ANALYST   |
| FORD   | ANALYST   |
+--------+-----------+

🤷🏻‍♂️ 책에서 나온 결과셋과 다르게 출력되었다

  • 'JOB'의 마지막 두 문자를 기준으로 정렬한다면 'A E N R S'순이 맞다
    이 부분은 출판사에 문의를 해봐야겠다

  • SUBSTR(열 이름, 가져오기 시작할 문자의 위치)
    가져오기를 시작할 문자의 위치를 정해주면, 해당 문자를 포함하면서 뒤의 나머지 값을 모두 반환한다

  • length()함수는 파라미터의 길이를 가져온다
    'job'을 넣었으니 해당 값이 가지고 있는 문자의 개수를 반환할 것이다
    문자의 개수는 문자열의 길이가 되고, 각 문자의 위치가 된다

알기 쉽게 한번 응용해보겠다.

select ename, length(ename) as 'length of ename' 
	from emp
>>
+--------+-----------------+
| ename  | length of ename |
+--------+-----------------+
| SMITH  |               5 |
| ALLEN  |               5 |
| WARD   |               4 |
| JONES  |               5 |
| MARTIN |               6 |
| BLAKE  |               5 |
| IREN   |               4 |
| CLARK  |               5 |
| SCOTT  |               5 |
| KING   |               4 |
| TURNER |               6 |
| ADAMS  |               5 |
| JAMES  |               5 |
| FORD   |               4 |
| MILLER |               6 |
+--------+-----------------+

select ename, substr(ename, length(ename)-3) as 'ename start from len-3' 
	from emp;
>>
+--------+------------------------+
| ename  | ename start from len-3 |
+--------+------------------------+
| SMITH  | MITH                   |
| ALLEN  | LLEN                   |
| WARD   | WARD                   |
| JONES  | ONES                   |
| MARTIN | RTIN                   |
| BLAKE  | LAKE                   |
| IREN   | IREN                   |
| CLARK  | LARK                   |
| SCOTT  | COTT                   |
| KING   | KING                   |
| TURNER | RNER                   |
| ADAMS  | DAMS                   |
| JAMES  | AMES                   |
| FORD   | FORD                   |
| MILLER | LLER                   |
+--------+------------------------+
  • SELECT절에서 'ename'과 length(ename)을 요소로 선택했다
  • length(ename)은 'ename'의 길이(문자 개수)를 반환할 것이다
  • 마찬가지로 as를 붙여, 필요한 상황에 알맞게 사용하면 될 것 같다
    응용 방법은 얼마든지 있을 것이다

2. 4 혼합 영숫자 데이터 정렬하기

Q. 혼합 영숫자(alphanumeric) 데이터가 있을 때 숫자 또는 문자 부분을 기준으로 정렬하려고 한다

A. REPLACETRANSLATE 함수를 아용하여 정렬할 문자열을 수정한다

MariaDB에는 TRANSLATE가 없다

🙅🏻‍♂️ 정말 안타깝게도 MySQL/MariaDB에서는 TRANSLATE를 지원하지 않고 있다

따라서 이 부분은 추후 Oracle을 설치하여 풀이를 해볼 것이다.

지금은 문제에서 나온 view에 대해 알아보려고 한다.


VIEW란 무엇인가?

1개 혹은 그 이상의 테이블에서 사용자가 원하는 정보를 섞어서 만든 가상의 테이블이다.

  • VIEW는 기존 테이블의 자료를 참조한다
    따라서 기존 테이블의 정보에 변동이 있으면 VIEW에도 당연히 반영된다

  • 조회는 자유로우나 나머지 작업에 대해서는 제약이 존재한다

create view V
as
	select concat(ename, ' ', deptno) as data
    from emp
    
select * from V

>>
+-----------+
| data      |
+-----------+
| SMITH 20  |
| ALLEN 30  |
| WARD 30   |
| JONES 20  |
| MARTIN 30 |
| BLAKE 30  |
| IREN 10   |
| CLARK 10  |
| SCOTT 20  |
| KING 10   |
| TURNER 30 |
| ADAMS 20  |
| JAMES 30  |
| FORD 20   |
| MILLER 10 |
+-----------+
  • 이런 식으로 원하는 정보만 모아서 임시의 테이블을 만들 수 있는데 이를 VIEW라고 한다
  • VIEW도 테이블이기 때문에 FROM절의 대상이 된다는 것을 위의 쿼리에서 볼 수 있다

참고 페이지
[oracle]CREATE VIEW - 뷰 생성 / 좋은 블로그


Oracle은 사용되는 곳이 많으므로 어차피 공부를 해야할 것 같다
2. 4장 이후의 내용은 Oracle을 설치하고 나서 계속 이어가도록 하겠다

0개의 댓글