본문 바로가기
개인공부/SQL 첫걸음

3장 - 정렬과 연산

by 하고싶은건많은놈 2023. 3. 29.

9. 정렬 - ORDER BY

SELECT명령의 ORDER BY구를 사용하여 검색결과의 행 순서를 바꿀 수 있음
SELECT 열명 FROM 테이블명 WHERE 조건식 ORDER BY 열명의 형식을 사용
검색 조건이 필요하지 않은 경우엔 WHERE 구를 생략 가능함

  • ORDER BY 열명 혹은 ORDER BY 열명 ASC의 형식으로 사용할경우 해당 열을 오름차순으로 정렬
  • ORDER BY 열명 DESC의 형식으로 사용할경우 해당 열을 내림차순으로 정렬

수치형 데이터 / 날짜시간형 데이터는 숫자의 크기로 대소관계를 판별하여 정렬
문자열형 데이터는 사전식 순서에 의해 결정
문자열형 열에 숫자를 저장할 경우 문자로 인식되므로 정렬 및 비교연산 사용시 주의가 필요
ORDER BY는 출력 결과에서만 정렬된 상태로 참조할 뿐, 저장장치에 저장된 데이터의 행 순서 자체를 변경하는 것은 아님


10. 복수의 열을 지정해 정렬하기

ORDER BY를 사용하지 않을 경우 같은 값을 가진 행의 경우 출력 순서는 데이터베이스 서버의 당시 상황에 따라 달라져 일정하지 않게 됨
따라서 언제나 같은 결과를 얻고 싶다면 ORDER BY 구를 지정해야함

ORDER BY 복수지정

SELECT 열명 FROM 테이블명 WHERE 조건식 ORDER BY 열명1 ASC, 열명2 DESC ...;
위와 같은 형식으로 ,를 통한 나열으로 복수의 열을 지정하여 정렬함
ASC의 경우 기본값이기 때문에 생략이 가능하나 데이터베이스 제품에 따라 기본값이 다를 수 있고, 가독성이 나빠지므로 되도록 생략하지 말고 지정하는 것 이 좋음

NULL값을 가진 행의 경우 정렬시 가장 먼저 표시되거나 혹은 가장 나중에 표시되며, 이는 표준 SQL에 규정되어있지 않아 데이터베이스 제품에 따라 기준이 다름
MySQL의 경우 NULL값을 가장 작은 값으로 취급하여 ASC에서는 가장 먼저 / DESC에서는 가장 나중에 표시함


11. 결과 행 제한하기 - LIMIT

SELECT 명령에서 결과값으로 반환되는 행을 제한하기 위해 사용
표준 SQL이 아니며 MySQL과 PostgreSQL에서 사용할 수 있는 문법

LIMIT

SELECT 열명 FROM 테이블명 WHERE 조건식 ORDER BY 열명 LIMIT 행수
위와 같은 형식으로 최대 행수를 수치로 지정하여 사용
WHERE 조건식과 ORDER BY의 정렬을 모두 거친 후 최종적으로 처리됨

SELECT 열명 FROM 테이블명 WHERE 조건식 LIMIT 행수 OFFSET 위치의 형식으로 LIMIT의 결과값으로부터 오프셋된 데이터를 출력할 수 있음
OFFSET을 생략하는 경우에는 기본값인 0으로 지정됨
OFFSET은 페이지 나누기(pagination)기능에 유용하게 사용할 수 있음

LIMIT 사용이 불가능한 경우

SQL Server의 경우 LIMIT 대신 SELECT TOP 행수 * FROM 테이블명;의 형식으로 TOP을 사용
Oracle에서는 SELECT * FROM 테이블명 WHERE ROWNUM <= 행수의 형식으로 ROWNUM을 사용
그러나 WHERE 구에 종속되기 때문에 LIMIT의 결과값과는 다를 수 있음


12. 수치 연산

SQL은 기본적으로 계산기능을 포함
산술 연산자인 +, -, *, /, %를 사용 가능

NULL 연산의 결과는 모두 NULL로 처리

SELECT 구로 연산

SELECT 식1, 식2... FROM 테이블명의 형식으로 연산 가능
연산자와 피연산자 사이에 공백을 반드시 넣을 필요는 없음

연산으로 지정한 식이 열의 이름으로 명명됨
SELECT 식 AS 별명 FROM 테이블명의 형식으로 AS 예약어를 사용하여 열 이름을 새롭게 재지정할 수 있음
AS는 생략 가능하며, 별명으로 한글과 같이 ASCII문자 이외의 것을 지정하고자 하는 경우에는 "(더블쿼트) 혹은 \(백쿼트)로 둘러싸서 데이터베이스 객체의 이름으로 간주시켜야 함

  • 데이터베이스 객체의 이름이라고 간주된 경우 예약어를 사용할 수 있고, 숫자로 시작할 수 있음
  • 그렇지 않을 경우에는 예약어와 숫자로 시작이 모두 금지됨

WHERE 구에서 연산

WHERE 조건식의 조건식에 수치 연산을 포함한 연산이 가능
단, 데이터베이스 서버 내부에서 WHERE구 -> SELECT구의 순서로 처리가 이루어지기 때문에 SELECT구에서 붙인 별명을 WHERE에서 사용할 수는 없음

ORDER BY 구에서 연산

ORDER BY 구에서도 ORDER BY 식의 형태로 연산 처리가 가능함
ORDER BY 구는 가장 마지막에 처리되기 때문에 SELECT 구에서 지정한 별명을 사용할 수 있음

함수

연산자 외의 함수를 사용한 연산도 가능

  • ROUND 함수 : 반올림 함수, 첫번째 인자로 반올림할 열을 받고 두번째 인자로 반올림할 자릿수를 지정함
    두번째 인자가 없을 경우 기본값인 0으로 간주되어 소수점 첫째 자리를 반올림함
  • 그 외에도 TRUNCATE, SIN, COS, SQRT, LOG 등등 많은 함수가 제공됨

13. 문자열 연산

+ / || / CONCAT / SUBSTRING / TRIM / CHARACTER_LENGTH 등의 명령어가 존재

문자열 결합

데이터베이스 제품마다 다른 방언을 사용

  • SQL Server는 +를 사용, 문자열 + 문자열의 형식
  • Oracle, DB2, PostgreSQL은 ||을 사용, 문자열 || 문자열의 형식
  • MySQL은 CONCAT을 사용, CONCAT(문자열, 문자열)의 형식

수치 데이터도 결합할 수 있으나, 결합 결과는 문자열형이 됨

SUBSTRING 함수

문자열의 일부분을 계산해서 반환
데이터베이스에 따라 함수명이 SUBSTR인 경우도 있음
SUBSTRING(문자열, a, b)의 형식으로 사용하며 a번째 문자부터 b번째 문자까치 추출함

TRIM 함수

문자열의 앞뒤로 여분의 공백이 있을 경우 이를 제거
문자열 도중에 존재하는 스페이스는 제거되지 않음
CHAR형 문자열과 같이 문자열의 길이가 고정되어있을 경우 빈 공간을 채우기 위해 사용된 공백을 제거하는데 사용할 수 있음
TRIM(문자열)의 형식으로 사용하며, 인수 사용시 공백 이외의 문자를 제거할 수도 있음

CHARACTER_LENGTH 함수

문자열의 길이를 문자 단위로 계산하여 리턴하는 함수
CHAR_LENGHT로 함수명을 줄여서 사용할 수 있음
OCTET_LENGTH의 경우 바이트 단위로 계산해 리턴함

  • 단, 이 때 문자세트에 따라 한 문자당 바이트 수가 다르기 때문에 주의해야함

14강 날짜 연산

CURRENT_TIMESTAMP / CURRENT_DATE / INTERVAL 등의 명령어가 존재
날짜 및 시간 데이터를 저장하는 방법은 데이터베이스 제품에 따라 차이가 큼

  • 날짜와 시간 전부를 저장할 수 있는 자료형을 지원
  • 날짜는 DATE형, 시간은 TIME형, 날짜와 시간은 DATETIEM형으로 나눔

SQL에서의 날짜

날짜나 시간 데이터도 사칙 연산이 가능
결과값으로 동일한 날짜시간 유형의 데이터를 반환하는 경우도 있고, 기간형(interval) 데이터를 반환하는 경우도 있음

시스템 날짜 : 하드웨어 상의 시계로부터 실시간으로 얻을 수 있는 일시적인 데이터

  • RDBMS에서도 시스템 날짜와 시간을 확인하는 함수를 제공함
  • 표준 SQL에서는 CURRENT_TIMESTAMP 함수로 실행했을 때를 기준으로 시간을 표시
    CURRENT_TIMESTAMP는 인수를 필요로하지 않으며, 괄호도 사용하지 않는 특수한 함수임
  • Oracle에서는 SYSDATE 함수, SQL Server에서는 GETDATE 함수를 사용할 수도 있으나 표준화 전에 구현된 함수이므로 권장되지는 않음

날짜 서식은 국가별로 다르며, 대부분의 데이터베이스 제품은 날짜 서식을 임의로 지정할 수 있는 함수를 지원
Oracle의 경우 TO_DATE 함수를 사용해 TO_DATE('2022/07/20', 'YYYY/MM/DD')의 형식으로 문자열 데이터를 원하는 서식을 가진 날짜형 데이터로 변환할수 있음

날짜의 덧셈과 뺄셈

날짜시간형 데이터는 기간형 수치데이터와 덧셈 및 뺄셈이 가능
CURRENT_DATE : 시스템 날짜만 확인하는 함수
INTERVAL N DAY : N일 후라는 의미의 기간형 상수

  • 단, 기간형 상수의 기술방법은 데이터베이스마다 다르며 표준화가 세세하게 이루어지지 않았음

두 날짜시간형 데이터간의 뺄셈을 통해 날짜의 차이를 구할 수 있음
MySQL에서는 DATEDIFF('2022-08-30', '2022-08-01')의 형식으로 계산 가능


15강 CASE문으로 데이터 변환하기

CASE문

간단한 상황의 경우 사용자 정의 함수를 작성하는 대신 CASE문으로 처리할 수 있음

CASE WHEN 조건식1 THEN 조건식2
[ WHEN 조건식2 THEN 식2 ... ]
[ ELSE 식3 ]
END

WHEN 절에 참과 거짓을 반환하는 조건식을 기술하여, 참일 경우 THEN 절에 기술한 식을 처리
거짓일 경우 다음 WHEN 절의 조건식을 차례로 평가하며, 어떠한 조건식도 만족하지 못한 경우 ELSE 절에 기술한 식을 채택함
ELSE는 생략 가능하며 생략했을 경우 ELSE NULL로 간주됨

또 하나의 CASE문

디코드 : 수치 데이터를 정보로 변환
인코드 : 정보를 수치 데이터로 변환
디코드를 CASE 문으로 처리할 수 있음

--검색 CASE
SELECT a AS "코드",
CASE
    WHEN a = 1 THEN '남자'
    WHEN a = 2 THEN '여자'
    ELSE '미지정'
END AS "성별" FROM sample37;

--단순 CASE
SELECT a AS "코드",
CASE a
    WHEN 1 THEN '남자'
    WHEN 2 THEN '여자'
    ELSE '미지정'
END AS "성별" FROM sample37;

검색 CASE : 위에서 설명한 형태의 CASE
단순 CASE : CASE에서 비교할 항목을 따로 지정하여 WHEN에는 비교할 값만 기술할 수 있음

CASE 사용시 주의사항

CASE문은 SELECT구 뿐만 아니라 WHERE구, ORDER BY구 등 어디에나 사용할 수 있음
ELSE를 생략할시 ELSE NULL이 되기 때문에 생략하지 않는 편이 권장됨

단순 CASE에서 WHENNULL을 지정할 경우 NULL은 비교 연산자로 비교할 수 없으므로 어떠한 경우에도 참이 되지 않음
따라서 NULL값을 판정하기 위해서는 IS NULL을 사용해야 함

Oracle에서는 디코드를 수행하는 DECODE함수가 내장되어있음
NULL값을 반환하는 함수의 경우 Oracle에는 NVL, SQL Server에는 ISNULL 함수가 있으나 특정 데이터베이스에 국한된 함수이므로, NULL값을 반환할 때는 표준 SQL로 규정된 COALESCE 함수를 사용함

댓글