# 12강. 수치 연산 **`산술연산`** ``` + - * / % MOD ``` - 어떤 계산을 할지는 연산자를 이용해 지정한다. - `WHERE` 구에서 조건을 지정할 때 사용했던 `=` 역시 연산자의 하나이다. ## 1. 사칙연산 - 덧셈, 뺄셈, 곱셈, 나눗셈의 사칙 연산과 나눗셈의 나머지 |연산자|연산|예| |-|-|-| |+|덧셈(가산)|1+2 -> 3| |-|뺄셈(감산)|1-2 -> -1| |\*|곱셈(승산)|1*2 -> 2| |/|나눗셈(제산)|1/2 -> 0.5| |%|나머지|1%2 -> 1| - 곱셈은 `x` 기호를 사용하지만 컴퓨터 언어에서는 `x` 기호가 존재하지 않아 대신 `애스터리스크(*)`를 사용한다. - `*`는 `모든 열`을 의미하는 메타 문자이지만 연산자로도 사용할 수 있다. - 컴퓨터 언어에서는 나눗셈 기호로 `슬래시(/)`를 사용한다. - 나머지는 나눗셈을 한 후의 나머지를 계산하는 것으로 `%` 기호를 사용한다. - 나머지 연산의 결과는 몫이 정수값이 되도록 계산하는 것이 특징이다. - 제품에 따라서는 `%` 대신 `MOD` 함수를 사용하는 경우도 있다. ##### 연산자를 사용해 여러 가지 연산을 할 수 있다! ### 연산자의 우선순위 |우선순위|연산자| |-|-| |1|* / % | |2|+ -| - 곱셈, 나눗셈, 나머지 그룹과 덧셈, 뺄셈 그룹으로 나뉜다. - 같은 그룹 내 연산자의 우선 순위는 동일하다. - 계산 순서는 연산자에 따라 관계없는 경우도 있지만 기본적으로 왼쪽에서 오른쪽으로 진행된다. - 우선순위가 같은 연산자들끼리 연산하는 경우는 문제가 되지 않지만 우선순위가 다른 연산자들이 섞여있는 경우는 우선순위가 높은 쪽이 먼저 계산된다. - `SQL` 명령에서는 여러 부분에서 산술 연산자를 사용해 연산할 수 있다. - `SELECT` 구나 `WHERE` 구 안에서도 연산할 수 있다. --- ## 2. SELECT 구로 연산하기 - `SELECT` 구에는 열명 외에도 여러 가지 식을 기술할 수 있다. - 이때의 식은 열명, 연산자, 상수로 구성된다. **`SELECT 구`** ``` SELECT 식 1, 식 2 ... FROM 테이블명 ``` - 식을 기술할 수 있다는 건 명령이 실행될 때 연산을 할 수 있다는 것을 의미한다. ``` SELECT *, price * quantity FROM sample34; ``` --- ## 3. 열의 별명 - 만약 열 이름이 길고 알아보기 어려운 경우는 별명을 붙여 열명을 재지정할 수 있다. **`SELECT 구에서 식에 별명 붙이기`** ``` SELECT *, price * quantity AS amount FROM sample34; ``` - 별명은 `예약어(AS)`를 사용해 지정한다. - `SELECT` 구에서는 `콤마(,)`로 구분해 복수의 식을 지정할 수 있으며, 각각의 식에 별명을 붙일 수 있다. - 별명을 지정할 때는 기본적으로 중복되지 않게 지정해야 한다(프로그래밍 언어에서 결괏값의 처리 방식에 따라 문제가 발생할 수 있다). - 키워드 `AS`는 생략할 수 있다. `SELECT price * quantity amount`라고 써도 무방하다. - `에일리어스(alias)`라고도 불리는 별명은 영어, 숫자, 한글 등으로 지정할 수 있다. - 단, 별명을 한글로 지정하는 경우에는 여러 가지로 오작동하는 경우가 많으므로 `더블쿼트(MySQL에서는 백쿼트)`로 둘러싸서 지정한다. - 이 룰은 데이터베이스 객체의 이름에 `ASCII` 문자 이외의 것을 사용할 경우에 해당한다. ``` SELECT price * quantity "금액" FROM sample34; ``` ##### 이름에 ASCII 문자 이외의 것을 포함할 경우는 더블쿼트로 둘러싸서 지정한다! - 더블쿼트로 둘러싸면 명령구문을 분석할 때 데이터베이스 객체의 이름이라고 간주한다. - 싱글쿼트로 둘러싸는 것은 문자열 상수이다. - 별명을 `예약어와 같은 이름은 지정할 수 없다`고 했지만 더블쿼트로 둘러싸서 지정하면 사용할 수 있다. ``` SELECT price * quantity AS "SELECT" FROM sample34; ``` - 이름을 붙일 때는 숫자로 시작할 수 없다. - 수치형 상수를 명령 안에서 사용할 경우에는 쿼트로 묶지 않고 숫자만 입력한다. - 이때 이름이 숫자로 시작한다면 그것이 수치형 상수를 의미하는 것인지 데이터베이스 객체명을 의미하는 것인지 구별할 수 없다. - 그에 따라 데이터베이스 객체명은 `숫자로 시작해서는 안 된다.` - 물론 이름이 예약어와 겹칠 때와 마찬가지로 더블쿼트로 묶으면 피할 수 있다. - `MySQL`에서는 숫자로 시작하는 객체명이 허용된다. - 다만 숫자만으로 구성되는 객체명은 허용되지 않는다. - 한편 `Oracle`에서는 숫자로 시작하는 이름은 허용되지 않는다. - 더블쿼트로 둘러싸면 객체명으로 간주하는 룰은 표준 SQL에 규정되어 있다. ##### 이름을 지정하는 경우 숫자로 시작되지 않도록 한다! --- ## 4. WHERE 구에서 연산하기 - `SELECT` 구에 이어, 지금부터는 `WHERE` 구에서의 연산 또한 가능하다. - `WHERE` 구의 조건식은 `price * quantity`일 때, `price * quantity`로 금액을 계산해 그 값이 2000 이상인 행을 검색하라는 뜻이다. - 여기서 `price * quantity`를 계산할 때 `SELECT` 구에서 `amount`라는 별명을 붙였으므로 `WHERE` 구에도 `amount`로 지정하면 될 것 같지만 실제로 `SELECT` 명령을 실행해보면 `amount`라는 열은 존재하지 않는다는 에러가 발생한다. ``` SELECT *, price * quantity AS amount FROM sample34 WHERE amount >= 2000; ``` ### WHERE 구와 SELECT 구의 내부처리 순서 - `WHERE` 구에서의 행 선택, `SELECT` 구에서의 열 선택은 데이터베이스 서버 내부에서 `WHERE 구 -> SELECT 구`의 순서로 처리된다. - 표준 SQL에는 내부 처리 순서가 따로 정해져있지 않다. 하지만 `WHERE 구 -> SELECT 구` 순서로 내부처리를 하는 데이터베이스가 많다. - 따라서 `WHERE` 구로 행이 조건에 일치하는지 아닌지를 먼저 조사한 후에 `SELECT` 구에 지정된 열을 선택해 결과로 반환하는 식으로 처리한다. - 별명은 `SELECT` 구문을 내부 처리할 때 비로소 붙여진다. - 즉, `WHERE` 구의 처리는 `SELECT` 구보다 선행되므로 `WHERE` 구에서 사용한 별칭은 아직 내부적으로 지정되지 않은 상태가 되어 에러가 발생하는 것이다. ##### SELECT 구에서 지정한 별명은 WHERE 구 안에서 사용할 수 없다! --- ## 5. NULL 값의 연산 - `NULL` 값을 이용해 `NULL + 1`과 같은 연산을 하면 어떻게 될까요? - SQL에서는 `NULL` 값이 0으로 처리되지 않는다. - 즉, `NULL + 1`의 결괏값은 1이 아닌 `NULL`이다. - 나눗셈을 할때도 `NULL`이 0으로 처리되지 않는다는 것을 알 수 있다. - 따라서 `1 / NULL`을 계산해도 `NULL`이 0으로 처리되지 않아 에러가 발생하지 않고 결과는 `NULL`이 된다. ##### NULL로 연산하면 결과는 NULL이 된다! --- ## 6. ORDER BY 구에서 연산하기 - `ORDER BY` 구에서도 연산할 수 있고 그 결괏값들을 정렬할 수 있다. ``` SELECT *, price * quantity AS amount FROM sample34 ORDER BY price * quantity DESC; ``` - 위 명령어를 실행하면 `amount` 값이 내림차순으로 정렬된다. - `ORDER BY`는 서버에서 내부적으로 가장 나중에 처리된다. - 즉, `SELECT` 구보다 나중에 처리되기 때문에 `SELECT` 구에서 지정한 별명을 `ORDER BY`에서도 사용할 수 있다. ``` WHERE 구 -> SELECT 구 -> ORDER BY 구 ``` ##### ORDER BY 구에서는 SELECT 구에서 지정한 별명을 사용할 수 있다! --- ## 7. 함수 - 연산자 외에 함수를 사용해 연산할 수도 있다. - 함수는 다음과 같은 문법으로 표기한다. **`함수`** ``` 함수명 (인수1, 인수2 ...) ``` - 연산자는 기호에 따라 연산 방법이 결정된다. 한편 함수는 함수명에 따라 연산 방법이 결정된다. - 연산자는 좌우의 항목이 연산 대상이 된다. - 함수는 계산 대상을 인수로 지정한다. - 이때 인수는 함수명 뒤에 괄호로 묶어 표기한다. - 인수의 수나 구분 방법은 함수에 따라 다르며, 대부분의 함수는 1개 이상의 인수를 가진다. - 인수는 파라미터라고도 부르며, 연산자가 그러하듯 함수 역시 결괏값을 반환한다. - 이를 `함수의 반환값`이라고 부른다. ``` 10 % 3 -> 1 MOD(10, 3) -> 1 ``` ##### 함수도 연산자도 표기 방법이 다를 뿐, 같은 것이다! --- ## 8. ROUND 함수 - 반올림을 하는데 이때 사용되는 것이 `ROUND` 함수이다. **`ROUND로 반올림하기`** ``` SELECT amount, ROUND(amount) FROM sample34; ``` - `INTEGER` 형의 경우는 정수밖에 저장할 수 없기 때문에 소수점이 포함되는 열은 `DECIMAL` 형으로 정의한다. - `DECIMAL` 형은 열을 정의할 때 정수부와 소수부의 자릿수를 지정할 수 있는 자료형이다. 다시 말해 소수점을 포함하는 수치를 저장하는 자료형이다. ### 반올림 자릿수 지정 - `ROUND` 함수는 기본적으로 소수점 첫째 자리를 기준으로 반올림한 값을 반환한다. - 이때 `ROUND` 함수의 두 번째 인수로 반올림할 자릿수를 지정할 수 있다. - 해당 인수를 생략하는 경우는 0으로 간주되어, 소수점 첫째 자리를 반올림한다. 1을 지정하면 소수점 둘째 자리를 반올림한다. ``` SELECT amount, ROUND(amount, 1) FROM sample341; ``` - 음수로 지정해 정수부의 반올림할 자릿수도 지정할 수 있다. - `-1`을 지정하면 1단위, `-2`를 지정하면 10단위를 반올림할 수 있다. - 그 밖에도 반올림 외에 `버림`을 하는 경우도 있는데 이는 `TRUNCATE` 함수로 계산할 수 있다. - 이 외에도 다양한 함수가 존재한다(`SIN`, `COS`, `SQRT`, `LOG`, `SUM` 등). ---