12-1 사칙연산
SQL의 연산도 +(덧셈), -(뺄셈), *(곱셈), /(나눗셈), %(나머지) 로 기본 산술 연산과 동일하다. DB 제품에 따라 % 대신 MOD 함수를 사용하는 경우도 있다.
12-2 SELECT 구로 연산
↓SELECT *, price*quantity FROM sample34;
12-3 열의 별명(alias)
SELECT *, price*quantity AS amount FROM sample34;
예약어 AS
를 통해 별명을 지정할 수 있다.
AS
는 생략이 가능하다,
로 구분해 복수의 식을 지정하고 별명을 붙일 수 있다.""
로 둘러싸서 지정한다. SELECT
같은 예약어도 별명으로 지정할 수 있다.싱글쿼트는 문자열 상수로, 더블쿼트는 DB객체의 이름으로 인식된다
12-4 WHERE 구에서 연산
SELECT *, price*quantity AS amount FROM sample34 WHERE price*quantity >= 2000;
일반 WHERE
구처럼 테이블명 뒤에 지정하면 된다.
앞의 SELECT
구에서 amount라는 별명을 지어줬으니 WHERE
구에도 사용할 수 있지 않을까 싶지만, SELECT *, price*quantity AS amount FROM sample34 WHERE amount >= 2000;
로 적으면 amount는 존재하지 않는다는 에러가 발생한다.
이는 WHERE
구 - SELECT
구 순으로 내부처리되기 때문이다.
별명은 WHERE
구의 조건에 맞는 행을 먼저 검색한 후에 SELECT
구를 통해 선택 및 반환하는 식으로 처리된다.
12-5 NULL 값의 연산
NULL 값은 0이 아니다.
따라서 NULL+1, NULL*2, 1/NULL 등을 해도 결과값은 모두 NULL이다.
12-6 ORDER BY 구에서 연산
SELECT *, price*quantity AS amount FROM sample34 ORDER BY amount DESC;
ORDER BY
구는 서버 내부적으로 가장 나중에 처리되기 때문에 SELECT
구에서 지정한 별명을 사용할 수 있다.
WHERE
- SELECT
(별명지정) - ORDER BY
12-7 함수
함수명 (인수1, 인수2...)
로 함수를 이용할 수 있다.
10%3 과 MOD(10,3)
처럼 함수는 기본적으로 연산자와 표기법이 다를 뿐, 같은 것이다.
12-8 ROUND 함수
SELECT amount, ROUND(amount) FROM sample341;
amount 열은 소수부의 자릿수를 지정할 수 있는 DECIMAL
형으로 정의되어있다. ROUND
함수는 반올림에 사용하는 함수다.
디폴트값은 소수점 첫째 자리에서 반올림하고,
ROUND(amount,1)
처럼 두 번째 인수를 지정해 반올림할 자리수를 지정할 수 있다.
ROUND(amount,-2)
처럼 음수값으로 지정하면 정수부의 자리수에서 반올림된다.
외에도 버림하는 TRUNCATE
함수, SIN
, COS
, SQRT
, SUM
등 여러가지 함수가 있다.
13-1 문자열 결합
연산자 | 데이터 베이스 |
+ | SQL server |
|| | Oracle, DB2, PostgreSQL |
CONCAT | MySQL |
DB 종류에 맞는 연산자로 문자열을 결합할 수 있다.
수치 데이터와도 결합할 수 있고, 결과는 문자열형으로 반환된다.
↓SELECT CONCAT(quantity, unit) FROM sample35;
13-2 SUBSTRING 함수
SUBSTRING
은 문자열의 일부분을 계산해 반환해주는 함수다. DB에 따라 SUBSTR
으로 사용한다.
YYYYMMDD 와 같은 형식의 문자열 데이터에서 년,월,일을 추출하는 경우 등에 쓰인다.
SUBSTRING('20210124',1,4) → '2014'
SUBSTRING('20210124',5,2) → '01'
13-3 TRIM 함수
TRIM
은 문자열 앞뒤 여분의 스페이스를 제거해주는 함수다.
CHAR형의 문자열에서는 문자열의 길이가 고정되고 남은 공간은 스페이스로 채워지는데, 이처럼 빈 공간을 채우기 위한 스페이스를 제거할 때 사용할 수 있다.
TRIM(' ABC ') → 'ABC'
인수를 지정해 스페이스 이외의 문자를 제거할 수도 있다.
13-4 CHARACTER_LENGTH 함수
CHARACTER_LENGTH
, 줄여서 CHAR_LENGTH
는 문자열의 길이를 계산해주는 함수다.
VARCHAR
형은 가변 길이이므로 길이가 서로 다르기 때문에, CHAR_LENGTH
함수를 사용하면 문자열의 길이를 문자 단위로 반환받을 수 있다.
OCTET_LENGTH
는 문자열의 길이를 바이트 단위로 반환한다. 문자세트(character set), 즉 문자의 인코드 방식에 따라 필요한 저장공간의 크기가 달라지기 때문에 OCTET_LENGTH
함수를 잘 사용해야 할 필요가 있다.
문자코드 | ASCII | 한글 |
ECU-KR | 1 byte | 2 byte |
UTF-8 | 1 byte | 3 byte |
날짜시간 데이터를 저장하는 방법은 DB에 따라 크게 달라진다.
날짜와 시간 전부를 저장할 수 있는 데이터형을 지원하거나, 날자는 DATE
형, 시간은 TIME
형, 날짜와 시간은 DATETIME
형과 같이 세분화해서 지원하는 제품들도 있다.
14-1 SQL에서의 날짜
날짜시간 데이터도 사칙연산을 지원한다. 결과값은 동일하게 날짜시간 유형의 데이터나 "10일간", "2시간 10분"과 같은 기간형(interval)
로 반환받을 수 있다.
CURRENT_TIMESTAMP
는 시스템 날짜와 시간을 확인하는 함수이다.
SELECT CURRENT_TIMESTAMP;
로 사용가능하지만, Oracle 등의 전통 DB에서는 FROM
구를 생략할 수 없다.
또한 Oracle의 SYSDATE
, SQL Server의 GETDATE
함수로도 시스템날짜를 확인할 수 있지만, 표준 SQL이 아닌 만큼 지양하는 편이 좋다.
임의의 날짜를 저장하고 싶은 경우 직접 서식을 지정하는 것도 가능하다. 국가별로 날짜 서식이 다르기 때문에 Oracle 의 경우 TO_DATE
함수를 이용해 문자열 데이터를 날짜형 데이터로 변환하거나, TO_CHAR
을 통해 그 역으로도 변환이 가능하다.
TO_DATE('2021/01/24','YYYY/MM/DD')
14-2 날짜의 덧셈과 뺄셈
SELECT CURRENT_DATE +- INTERVAL 1 DAY;
날짜시간형 데이터는 +- 연산을 통해 특정일로부터 1일 전, 1일 후 등을 계산할 수 있다.
SELECT DATEDIFF('2021-01-24','2021-01-01')
등으로 두 날짜 사이의 차이를 계산할 수 있다.
15-1 CASE문
CASE WHEN 조건식1 THEN 식1
[WHEN 조건식2 THEN 식2]
[ELSE 식3]
END
WHEN
절에는 참과 거짓을 반환하는 조건식을 기술한다. 참인 경우 THEN
절의 식이 처리되고, 조건식에 전부 거짓일 경우는 ELSE
절의 식이 채택된다. ELSE
를 생략할 경우 ELSE NULL
로 간주된다.
SELECT * FROM sample37;
SELECT a, CASE WHEN a IS NULL THEN 0 ELSE a END "a(null=0)" FROM sample37;
위는 a값이 NULL
인 경우 0, 아닐 경우 a를 반환하는 a(null=0)
열을 구현한 CASE
식이다.
사실 NULL
값을 반환하는 경우는 COALESCE
함수로 이미 구현되어있다. COALESCE
함수는 여러개의 인수를 지정해 NULL
이 아닌 값에 대해서는 첫번째 인수를, NULL
에 대해서는 다음 인수를 반환한다.
SELECT a, COALESCE(a,0) FROM sample37;
15-2 또 하나의 CASE문
숫자로 이루어진 코드를 알아보기 쉽게 문자열로 반환하고 싶은 경우 CASE
문을 많이 사용한다. 이와 같이 코드를 문자화하는 것을 디코드
, 반대로 수치화하는 것을 인코드
라고 부른다.
다음은 숫자가 1일 경우 남자, 2일 경우 여자, 외의 경우에는 미지정을 출력하는 검색 케이스문이다.
↓SELECT a AS "코드", CASE WHEN a=1 THEN '남자' WHEN a=2 THEN '여자' ELSE '미지정' END AS "성별" FROM sample37;
이 식을 단순 케이스문으로 변경하면 CASE
문에서 비교항목인 a를 따로 지정하므로 WHEN
에는 값만 기술하면 된다.
SELECT a AS "코드", CASE a WHEN 1 THEN '남자' WHEN 2 THEN '여자' ELSE '미지정' END AS "성별" FROM sample37;
15-3 CASE를 사용할 경우 주의사항
CASE
문은 SELECT
, WHERE
, ORDER BY
어디든 사용할 수 있다.
또한 ELSE
를 생략하면 ELSE NULL
이 되기 때문에, 상정한 것 이외의 데이터가 들어오면 NULL
이 반환된다. 따라서 ELSE
는 생략하지않고 지정하는 것이 좋다.
또한 WHEN
에서 NULL
을 지정할 때에는 검색 케이스문을 써야한다. 단순 케이스문은 특성상 =
연산자로 비교하기 때문에, NULL
값인지 확인하는 IS NULL
을 사용하려면 검색 케이스문을 써야한다.