수치 연산
SQL은 기본적으로 계산 기능을 포함하고 있습니다. 이번에는 이런 계산하는 기능을 사용하는 방법 중 수치 데이터의 연산에 대해 이야기 하겠습니다. 수치 연산을 하는 산술 연산의 경우는 다른 프로그래밍에서도 사용하는 기본 개념이니 기존에 프로그래밍을 하셨던 분들은 익숙하실 수 있고, 처음 접하시는 분은 이번에 잘 알아두길 바랍니다.
사칙 연산
사칙 연산은 우리가 알고 있는 덧셈, 뺄셈, 곱셈, 나눗셈에 한가지 더 있다면 나눗셈의 나머지를 구하는 것 입니다. 연산자는 기호로 표기하고 아래 표로 정리해 보겠습니다.
연산자 | 연산 | 예 |
+ | 덧셈 | 1+2 → 3 |
- | 뺄셈 | 1-2 → -1 |
* | 곱셈 | 1*2 → 2 |
/ | 나눗셈 | ½ → 0.5 |
% | 나머지 | 1%2 → 1 |
[표 9. 산술 연산자]
[표 9]의 연산자들은 여러 데이터베이스에서 동일하게 사용합니다. 하지만 나머지를 구하는 %는 데이터베이스 제품마다 차이가 있을 수 있습니다. 보통은 % 또는 MOD 함수를 사용하는 경우도 있습니다.
산술 연산자는 우선 순위가 있습니다. 하지만 이미 산수를 다 알고 계실 것이라 생각합니다. 간단하게 표로 정리하고 넘어 가겠습니다.
우선순위 | 연산자 |
1 | * / % |
2 | + - |
[표 10. 산술 연산자 우선순위]
지금까지 SQL에서 사용하는 산술 연산자에 대해 간단히 알아 보았습니다. 그러면 쿼리에서 산술 연산자는 어디서 사용하는지 알아 보겠습니다.
SELECT 구에서 연산
SELECT 구에는 컬럼명을 지정할 수도 있지만 여러가지 식을 기술할 수 있습니다. 여기서 사용하는 식은 컬럼명, 연산자, 상수로 구성됩니다.
1 | SELECT *, 컬럼명1 * 상수 FROM 테이블명; |
[표 11. SELECT 구에서 식의 사용]
[그림 8. SELECT 구에서 식을 사용한 결과]
위 예제의 결과를 보면 사용한 식의 내용이 결과의 컬럼명이 사용한 식의 내용으로 들어가 있는것을 볼 수 있습니다. 식이 그대로 보이면 이름이 길고 사용하기도 불편하고 알아보기도 어렵습니다. 이것을 바꾸는 방법을 알아 보겠습니다.
컬럼 별명 설정
SELECT에서 사용한 식의 결과에서 결과 컬럼명을 내가 원하는 이름으로 재지정할 수 있습니다. 바로 예약어 AS를 사용하는 것입니다.
1 | SELECT *, 컬럼명1 * 상수 AS 별명 FROM 테이블명; |
[표 12. AS를 사용한 컬럼 별명 지정]
[그림 9. AS를 사용하여 별명을 지정한 결과]
SELECT 구에서는 콤마(,)로 구분한 복수의 식을 지정할 수 있고 각각의 식에 별명을 붙일 수 있습니다. 중복의 이름을 사용할 수는 있지만 결과의 처리가 불분명해집니다. 중복되지 않게 사용해야 합니다.
예약어 AS는 생략할 수 있습니다. 그리고 별명을 지정할 때 한글로 지정하는 경우에는 더블쿼트로 감싸야 합니다. 감싸지 않아도 동작을 하는 경우가 있을 수 있으나 오작동하는 경우들이 많이 발생합니다. 그렇기 때문에 감싸주는것이 좋습니다.
1 | SELECT *, 컬럼명1 * 상수 “별명” FROM 테이블명; |
[표 13. AS의 생략과 한글의 더블쿼드 사용]
[그림 10. AS를 제외하고 한글 별명을 사용한 결과]
또한 별명을 붙일 때는 숫자로 시작할 수 없습니다. 이름이 숫자로 시작한다면 그것이 수치형 상수를 의미하는 것인지 데이터베이스 객체명을 의미하는지 구별할 수 없습니다. 그래서 데이터베이스명은 ‘숫자로 시작하면 안된다'라는 제약이 생겼습니다. 더블쿼트로 묶는다면 사용할 수는 있지만 추천하지는 않습니다.
WHERE 구에서 연산
SELECT 구에서 연산을 할 수 있지만 WHERE에서도 연산이 가능합니다.
1 | SELECT *, 컬럼명 * 상수 AS “별명" FROM 테이블명 WHERE 컬럼명 * 상수 >= 비교값; |
[표 14. WHERE 구에서 식의 사용]
[표 14]와 같이 WHERE 구에서 식을 사용할 수 있습니다. 여기서 WHERE 구의 컬럼명 * 상수 부분을 SELECT 구에서 정의한 별명인 “별명"으로 사용하면 안되는지 궁굼할 수 있습니다. 결론은 안된다 입니다. 그 이유는 쿼리의 내부 처리 순서가 다르기 때문입니다.
데이터베이스 서버 내부에서는 WHERE 구를 먼저 처리하고 SELECT 구를 처리합니다. 그래서 SELECT 구에서 지정한 별명은 WHERE 구 안에서 사용할 수 없습니다.
NULL 값의 연산
NULL을 이용해서 연산을 어떻게 결과가 나올지 한번 보겠습니다.
‘NULL + 1’을 했을 때 결과가 어떻게 나올까요?
많은 분들이 1이라고 대답을 합니다. 왜 그럴까요? 아마도 다른 언어의 프로그래밍에서는 NULL을 0으로 간주해서 계산을 했기 때문입니다.
SQL에서 NULL은 유효한 값이 없는 상태입니다. NULL은 0이 아닙니다. 그래서 NULL에 어떤 연산을 하더라도 결과는 NULL입니다.
ORDER BY에서 연산
ORDER BY에서 연산은 다른것은 아니고 SELECT 구에서 지정한 식의 결과를 ORDER BY에서 정렬이 가능합니다.
1 | SELECT *, 컬럼명 * 상수 AS “별명" FROM 테이블명 ORDER BY “별명”; |
[표 15. 식의 결과로 정렬하기]
[그림 11. order by에서 별명을 지정한 결과]
[표 15]를 보면 조금 이상한 부분 없으신가요?
WHERE 구를 설명할 때는 SELECT에서 지정한 별명을 WHERE 구에서 사용할 수 없다고 설명했습니다. 근데 ORDER BY에서는 별명을 사용하고 있습니다. 무엇이 다른것일까요?
네. 쿼리의 처리 순서가 여기서도 나옵니다. ORDER BY는 서버 내부에서 가장 나중에 처리됩니다. 그래서 SELECT 구에서 지정한 별명을 ORDER BY에서도 사용할 수 있는 것입니다.
함수
지금까지는 연산자를 사용해 보았습니다. 그렇지만 연산자만 사용하는 것은 아닙니다. 연산자외에도 함수를 사용할 수도 있습니다.
1 | SELECT 함수명(파라미터 1, 파라미터 2) AS “별명" FROM 테이블명; |
[표 16. 함수의 사용법]
데이터베이스 종류마다 제공하는 함수는 차이가 날 수 있습니다. 하지만 구조는 다 비슷합니다. 그러면 한가지 함수를 다음에서 설명해보겠습니다.
ROUND 함수
데이터가 소수점을 가지고 있을 경우 거래되는 단위를 고려해 반올림을 하는데 이때 사용하는 것이 ROUND 함수입니다.
1 | SELECT ROUND(컬럼명 또는 식) FROM 테이블; |
[표 17. ROUND 함수의 사용]
ROUND 함수는 기본적으로 소수점 첫째 자리를 기준으로 반올림한 값을 반환합니다. 첫째 자리를 기준으로 반올림할 수도 있지만 두번째 파라미터를 지정하여 반올림할 자릿수를 지정할 수 있습니다. 두번째 파라미터를 생략하는 경우는 0으로 간주해서 처째 자리를 반올림합니다. 만약 두번째 파라미터를 음수로 지정할 경우 정수부의 반올림할 자릿수도 지정할 수 있습니다.
반올림이 아니라 버림을 할때는 TRUNCATE을 사용할 수 있습니다.
이것 외에도 여러가지 함수들이 많이 있습니다. 그런것들은 사용하시는 데이터베이스의 메뉴얼을 참고해주세요.
문자열 연산
지금까지 수치형 데이터의 연산을 알아봤다면 지금은 문자열형 데이터의 연산에 대해 알아보겠습니다. 문자열형 데이터 연산은 연산자가 그렇게 많지가 않습니다. 그래서 자주 사용하는 몇가지 함수에 대해 표로 정리하겠습니다.
연산자/함수 | 설명 |
+/||/CONCAT | 문자열을 결합한다. SQL Server는 + Oracl, DB2, PostgreSQL 은 || MySQL 은 CONCAT 함수를 사용한다. |
SUBSTRING SUBSTR | 문자열의 일부분을 계산하여 반환해주는 함수 |
TRIM | 문자열의 앞뒤로 공백이 있을 경우 제거해주는 함수. 문자열 중간의 스페이스는 제거되지 않은다. |
CHARACTER_LENGTH | 문자열의 길이를 계산하는 함수 |
OCTET_LENGTH | 문자열의 길이를 바이트 단위로 계산하는 함수 문자 인코딩 설정에 따라 길이가 다를 수 있다. |
[표 18. 문자열 연산]
날짜 연산
날짜, 시간 데이터를 저장하는 방법은 데이터베이스마다 크게 다릅니다. 사용하는 데이터베이스의 날짜 저장 방식을 먼저 살펴 보시길 바랍니다.
실제 시스템에서 날짜 연산은 빈번하게 일어납니다. 날짜 정보를 유용하게 사용하는 법을 알아보겠습니다.
덧셈과 뺄셈
날짜형 데이터는 기간 형식의 수치 데이터와 덧셈, 뺄셈을 할 수 있습니다.날짜 데이터에서 기간 형식의 수치 데이터를 더하거나 빼면 됩니다.
예를 들기에는 기간형 상수의 기술 방법이 데이터베이스마다 다르고 세세한 부분까지 표준화가 이루어지지 않아서 어렵고 자세한 내용은 데이터베이스의 매뉴얼을 참고하길 바랍니다.
CASE 문으로 데이터 변환하기
CASE 문을 이용할 경우 데이터를 변환할 수 있습니다.
이미 준비된 함수를 사용해서 데이터를 특정한 형태로 변환하는 경우도 있지만 임의의 조건에 따라서 데이터를 변환하고 싶을 때 CASE 문을 사용합니다.
CASE 문이란?
먼저 CASE 문의 사용법을 보겠습니다.
1 | CASE WHEN 조건식 1 THEN 식 1 [ WHEN 조건식 2 THEN 식 2 ... ] [ ELSE 식3 ] END |
[표 19. CASE문의 사용]
WHEN 절에는 참과 거짓을 반환하는 조건식을 기술합니다. 조건을 만족하는 경우 THEN 절에 기술에 식을 처리합니다. 다수의 WHEN … THEN ...을 사용했을때 순차적으로 조건식을 실행하게 되고 어떤 조건식도 만족하지 않을때는 ELSE에 기술한 식을 처리합니다.
만약 NULL 값을 변환할 때 CASE를 사용해서 0으로 변환할 수 있습니다. 하지만 이때 CASE를 사용하는 것보단 COALESCE 함수를 사용하는 것이 더 쉽습니다.
1 | SELECT COALESCE(컬럼명, 0) FROM 테이블; |
[표 20. COALESCE 함수의 사용]
컬럼의 값이 NULL일 경우 0을 반환하고 아닐경우는 컬럼의 값을 그대로 반환합니다.
CASE의 다른 사용법
위에서는 CASE에서 식을 실행하는 것이었다면 여기서 설명할 내용은 숫자로 이루어진 코드를 알아보기 쉽게 문자열로 변환하는 것입니다.
예를 들어 1은 남자 2는 여자라는 코드 체계가 있다면 모르는 사람이 봤을 때 1, 2 코드를 보여주면 이해가 안되지만 남자, 여자라고 표시하면 이해하기 쉬울것입니다.
코드를 문자와 하는것은 ‘디코드', 문자를 수치화 하는것을 ‘인코드'라고 합니다.
1 | WHEN a=1 THEN ‘남자' WHEN a=2 THEN ‘여자' |
[표 21. CASE 문을 사용한 디코드]
주의 사항
ELSE를 생략하게 되면 ELSE NULL이 되는것에 주의해야 합니다. 조건에 만족하는 WHEN 절이 하나도 없을경우 ELSE가 사용되며 NULL을 반환합니다. 그렇기 때문에 NULL이 반환되지 않도록 ELSE로 반환될 값을 지정하는것이 좋습니다.
- WHEN에서 NULL인지 확인하기 위해서는 = 연산자를 사용하는 것이 아닌 IS NULL을 사용합니다. 단순한 비교 연산자 만으로는 NULL 값을 비교할 수 없습니다.
'IT > Database' 카테고리의 다른 글
05.01. 집계와 서브쿼리 - 집계 (0) | 2017.02.23 |
---|---|
04. 데이터의 추가, 삭제, 갱신 (0) | 2017.02.21 |
03.01. 정렬과 연산 - 정렬 (0) | 2017.02.17 |
02.04. 테이블에서 테이터 검색 - 검색 조건 조합 및 패턴 매칭 (0) | 2017.02.16 |
02.03. 테이블에서 데이터 검색 - 검색 조건 지정 (1) | 2017.02.15 |