본문 바로가기
CS/DataBase

데이터베이스 첫걸음 정리 - 12장. 수치 연산

by yongckim 2022. 9. 3.
728x90
반응형

사칙 연산

SQL에서도 다음과 같이 사칙연산이 가능합니다.

연산자 연산 예

+ 덧셈 1 + 2 → 3
- 뺄셈 1 - 2 → -1
* 곱셈 1 * 2 → 2
/ 나눗셈 1 /2 → 0.5
% 나머지 1 % 2 → 1

데이터베이스 제품에 따라 % 대신 MOD 함수를 사용하는 경우도 있습니다.

연산자의 우선순위의 경우 일반적으로 사칙연산 할때와 같이 나눗셈, 곱셈, 나머지를 먼저 계산하고 다음은 덧셈, 뺄셈을 계산합니다.

우선순위가 같다면 왼쪽에서 오른쪽으로 계산하게 됩니다.

SELECT 구로 연산하기

SELECT 구에는 열명을 지정한다고 학습했지만 이외에도 여러가지 식을 작성할 수 있습니다.

이 식은 열명, 연산자, 상수로 구성됩니다.

SELECT 식 1, 식 2... FROM 테이블명

다음은 SELECT 구에 연산식을 사용하는 예시입니다.

SELECT *, CategoryId * Price FROM Products

열의 별명 부여하기

SELECT에서 연산식을 사용하면 새로운 데이터를 만들 수 있지만 이름이 연산식과 같은 이름이 되기에 보기어려울 수 있습니다.

이 때 AS 구문을 사용하여 해당 식에 대한 별명을 부여할 수 있습니다.

SELECT *, CategoryId * Price AS 별명 FROM Products

각각의 식에 AS를 붙여 별명을 추가할 수 있습니다.

MySQL에서는 별명을 중복해서 지정해도 에러는 발생하지 않으며, 단, 프로그래밍 언어에서 결괏값의 처리 방식에 따라 문제가 발생할 수도 있습니다.

이 때문에 기본적으로 중복되지 않도록 지정하는 것이 좋습니다.

별명은 영어, 숫자, 한글등으로 지정할 수 있습니다.

단, 별명을 한글로 지정하는 경우 오작동할 수 있기 때문에 더블쿼트(”) 또는 백쿼트(`)로 둘러싸서 지정하는 것이 좋습니다.

💡 데이터베이스 객체의 이름에 ASCII 문자 이외의 것을 사용할때는 더블쿼트 또는 백쿼트(MySQL)로 둘러싸서 지정하는 것이 좋습니다.

더블쿼트로 둘러싸면 명령구문을 분석할 때 데이터베이스 객체의 이름이라고 간주하며, 싱글쿼트로 둘러싸는 것은 문자열 상수로 판단합니다.

예약어의 경우에도 더블쿼트로 둘러싸면 사용이 가능합니다.

SELECT *, CategoryId * Price AS "SELECT" FROM Products

또한 별명을 붙일때는 별명이 숫자로 시작할 수 없습니다.

단, 더블쿼트를 붙이면 숫자로 시작할 수 있습니다.

정리하면 다음과 같습니다.

  • 별명은 영어, 한글, 숫자, 특수문자 등 문자를 지정할 수 있습니다.
  • 별명은 같은 이름으로 하지 않는 것이 좋습니다.
  • 별명은 ASCII 문자가 아닌 문자로 지정할 경우 문제가 발생할 수 있기 때문에(한글, 특수문자 등) 이때는 더블쿼트를 사용하여 묶는 것이 좋습니다.
  • 별명은 숫자로 시작할 수 없습니다.
  • 별명으로 예약어를 사용할 수 없습니다.
  • 별명을 더블쿼트로 묶을 경우 여러 제약조건에 상관없이 사용할 수 있습니다.(숫자 시작 가능, 예약어 사용 가능)

WHERE 구에서 연산하기

SELECT 구에서 연산식을 사용했던 것 처럼 조건식에 연산식을 사용할 수 있습니다.

SELECT *, CategoryId * Price FROM Products WHERE CategoryId * Price >= 100

이번에는 이전에 배웠던 별명을 활용하여 다음과 같이 SQL 명령을 내려봅시다.

SELECT *, CategoryId * Price AS alias FROM Products 
WHERE alias >= 100

하지만 이를 실제 실행해보면 alias라는 열은 존재하지 않는 다는 에러가 발생합니다.

WHERE구와 SELECT 구의 내부처리 순서

WHERE 구에서의 행 선택, SELECT 구에서의 열 선택은 데이터베이스 서버 내부에서 WHERE 구 → SELECT 구의 순서로 처리됩니다.

SELECT *, CategoryId * Price AS alias FROM Products 
WHERE alias >= 100

위의 SQL이 에러가 발생한 이유는 서버의 처리 순서때문에 에러가 발생하는 것입니다.

💡 표준 SQL에는 내부처리 순서가 따로 정해져 있지 않기 때문에 정상적으로 작동하는 데이터베이스가 있을 수 있습니다. 하지만, WHERE → SELECT구의 순서로 내부 처리를 하는 데이터베이스가 많다는 점을 기억해둡시다.

즉, WHERE 구의 처리가 먼저 이뤄지고 SELECT의 처리가 이루어지기 때문에 SELECT에서 지정한 별명이 아직 적용되지 않았기 때문에 에러가 발생했다는 사실을 기억해둡시다.

NULL 값의 연산

NULL 값을 이용해 NULL + 1 과 같은 연산을 하면 결과를 어떻게 될까요?

다른 프로그래밍언어 경험이 있다면 1이라고 대답할 수도 있습니다.

하지만 C나 PHP 같은 경우 NULL이 0으로도 처리되지만 SQL에서는 NULL 값이 0으로 처리되지 않는 다는 점을 주의합시다.

SQL에서 NULL + 1의 결과값은 1이 아닌 NULL 입니다.

다음과 같은 연산들도 전부 NULL으로 처리됩니다.

  • NULL + 1
  • 1 + NULL
  • 1 + 2 * NULL
  • 1 / NULL

여기서 나눗셈을 보면 NULL이 0으로 처리되지 않는 다는 점을 알 수 있는데, 통상적인 연산에서는 0으로 1을 나누면 division by zero 에러가 발생하지만 SQL에서는 NULL이 0으로 처리되지 않아 에러가 발생하지 않고 결과가 NULL이 됩니다.

ORDER BY 구에서 연산하기

SELECT나 WHERE 구 이외에도 ORDER BY 구에서도 연산을 할 수 있습니다.

SELECT *, CategoryId * Price FROM Products ORDER BY CategoryId * Price DESC

ORDER BY는 서버에서 내부적으로 가장 나중에 처리되기 때문에 SELECT 구에서 별명을 지정하더라도 ORDER BY에서 사용할 수 있습니다.

SELECT *, CategoryId * Price AS alias FROM Products ORDER BY alias DESC

SELECT, WHERE, ORDER BY 구의 내부처리 순서는 다음과 같습니다.

  • WHERE → SELECT → ORDER BY

함수를 이용한 연산

연산자외에도 함수를 사용해 연산할 수도 있습니다. 함수는 다음과 같은 문법으로 표기합니다.

함수명(인수1, 인수2...)

함수는 종류에 따라 여러개의 파라미터를 받을 수 있으며, 연산한 결과값을 반환하게 됩니다.

다음은 나머지 연산을 하는 MOD 함수의 사용 예시입니다.

SELECT MOD(10, 3);

ROUND 함수

ROUND 함수를 사용하면 소수에 대해 반올림하여 나타낼 수 있습니다.

SELECT *, ROUND(Price) FROM Products;

반올림 자릿수 지정

ROUND 함수는 기본적으로 소수점 첫째 자리를 기준으로 반올림한 값을 반환합니다.

이때 다른 자리를 기준으로 반올림하고 싶다면 값을 추가적으로 지정해줄 수 있습니다.

SELECT *, ROUND(Price, 1) FROM Products;

ROUND의 두번째 인수를 생략하는 경우 기본적으로 0으로 간주되며, 소수점 첫째 자리를 반올림합니다.

다음과 같이 음수로 지정해 정수부의 반올림할 자릿수도 지정할 수 있습니다.

SELECT *, ROUND(Price, -1) FROM Products;

-1의 경우 1단위, -2를 지정하면 10단위를 반올림할 수 있습니다.

정리

  • SQL에서도 연산자를 사용하여 사칙연산이 가능합니다.
  • SELECT에서 AS를 통해 별명을 지정할 수 있습니다. 별명 사용시 ASCII 문자 이외의 문자를 사용시 더블 쿼트 또는 백 쿼트로 둘러싸서 지정하는 것이 좋습니다.
  • 더블 쿼트로 둘러싸면 데이터베이스 객체의 이름으로 간주하고, 싱글 쿼트로 둘러싸는 것은 문자열 상수로 판단합니다.
  • SQL이 처리될때 WHERE → SELECT → ORDER BY 순으로 처리됩니다.
  • NULL 연산시 결과가 항상 NULL 값입니다.
  • 함수를 사용해서 연산을 할 수도 있으며, ROUND 함수를 사용하면 소수의 반올림을 할 수 있습니다.
반응형