10. SQL 사칙연산

1. 10. 사칙연산

1.1. 사칙연산

연산자 연산
+ 덧셈(가산) 1+2->3
- 뺄셈(감산) 1-2->-1
* 곱셈(승산) 1*2->2
/ 나눗셈(제산) 1/2->05
% 나머지 1%2->1
  • 연산자 우선순위
우선순위 연산자
1 */%
2 ±
  • 산술 연산자는 곱셈,나눗셈,나머지 그룹과 덧셈,뺄셈 그룹으로 나뉩니다.

  • 계산순서는 연산자에 따라 왼쪽에서 오른쪽으로 진행합니다. 우선순위가 같은 연산자들 끼리 연산하는 경우 문제가 되지 않지만 우선순위가 다른 연산자들이 섞여있는 경우는 우선순위가 더 높은쪽으로 계산합니다.

  • 우선순위가 같은 경우

1-2+3=2 (우선순위가 같다면 왼쪽에서 오른쪽으로 계산합니다.)    
  • 우선순위가 다른 경우
1+2*3=7 (+보다 *의 우선순위가 높습니다.)    

1.2. select구로 연산하기

select1, 식2 ... from 테이블명    
  • 이 식은 열명, 연산자, 상수로 구성
  • 가격과 수량으로 금액을 계산하는 경우
    주문금액 = 단가 * 개수

예) 100원 상품 10개 주문 상품금액 1000원

select *, price * quantity from sample34    

1.3. 열의 별명

select *, price * quantity AS amount from sample34    
  • 열의 별명을 붙일때는 예약어 AS 를 사용한다. AS의 약어는 에일리어스(alias)입니다.
  • 별명은 중복이 되지 않도록 처리 한다.
  • AS 예약어 별명은 영어, 숫자, 한글 등으로 지정 가능합니다.
  • 단, 한글로 지정하는경우 더블쿼트 "" 를 지정해서 사용합니다
  • 다음과 같이 쓸 수 있습니다.
select price * quantity "금액" from sample34    

이 룰은 ASCII 문자 이외의 것을 포함할 경우 더블쿼트로 둘러싸서 지정합니다.

  • 문자열 상수는 ' ' 싱글쿼트로 감싸주고, 데이터베이스 객체명은 " " 더블쿼트로 감싸줍니다.
문자열 상수 'ABC', 'KGH' -> 싱글 쿼트    
데이터베이스 객체명 "sample21" "sample34" -> 더블쿼트    
  • 예약어 같은 경우는 별명을 지정해서 사용할 수 없는데, 그래도 사용해야한다면 " " 더블쿼트를 사용하면 가능합니다.
select price * quantity AS select from sample34; (예약어 지정 X)    
select price * quantity AS "select" from sample34; (예약어 지정 O)    
  • 숫자의 경우도 예약어와 겹칠때와 마찬가지로 " " 더블쿼트를 사용하면 피할 수 있습니다.
  • 오라클 기준으로 이름을 지정하는 할 수 없습니다. 이에 따라 숫자로 객체명이 시작되지 않도록 합니다.(단, mysql에서는 숫자로 시작하는 객체명이 허용됩니다.)

1.4. where 구에서 연산하기

  • where 구에서 가격 * 수량 금액을 계산하여 2000원 이상에 해당하는 행을 검색하는 쿼리
select *, price * quantity AS amount from sample34;    
select *, price * quantity AS amount from sample34    
where price * quantity >= 2000;    
  • price * quantity 대신에 amount를 사용하면 어떻게 될까요?
select *, price * quantity AS amount from sample34    
where amount >= 2000;    
  • AS 를 써서 별명을 지어줬으니 에러가 발생하지 않을까? 라는 생각을 할 수도 있습니다. 하지만, amount가 존재하지 않는다라는 에러가 발생하게 됩니다.
  • 데이터베이스 처리순서는 (where구 → select구) 의 순서로 진행됩니다. 즉, where 구의 처리는 select구보다 선행되므로 where 구에서 사용한 별칭을 인식하지 못하게 됩니다.
  • 다시 말해, where amount >= 2000; 를 실행하고 나서 select *, price * quantity AS amount from sample34 를 실행하기 때문에 amount를 인식하지 못하게 되는 상황이 발생하게 됩니다.
  • 표준 SQL에서는 내부처리 순서가 따로 정해져 있지 않습니다.

1.5. NULL 값의 연산

  • 만약 NULL값을 이용해 NULL+1 과 같은 연산을 사용하면 결과는 어떻게 될까요?

  • 어느 정도 짐작을 하셨겠지만, SQL에서는 NULL값을 0으로 인식하지 않습니다. 잘못 생각한 경우라면 NULL값을 1로 생각하여 1 이라는 결과를 얻을 수 있다고 생각하셨을 수도 있습니다.

  • 결과적으로, NULL+1 은 1이 아닌 NULL 입니다.

  • 다음 연산결과도 같은 결과를 나타냅니다.

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

NULL은 0으로 처리 되지 않고, 0을 1로 나누면 'division by zero' 라는 에러를 나타내게 할 것입니다.

하지만, 1/NULL의 경우는 NULL이 0으로 처리 되지 않아 에러가 발생하지 않고 NULL 의 값을 나타내게 될 것입니다.

1.6. order by구에서 연산하기

  • 금액을 오름차순, 내림차순을 구현하기 위해서는 어떠한 예약어를 사용하면 될까요?
select *, price * quantity AS amount from sample34;    
select *, price * quantity AS amount from sample34 order by price * quantity DESC;    
  • order by구를 사용하고 옵션으로 DESC(descending)키워드를 사용하면 내림차순 정렬이 되는것을 볼 수 있습니다. 오름차순(ascending) 정렬은 예약어 ASC로 사용하면 됩니다.
  • order by는 서버에서 내부적으로 가장 나중에 처리 됩니다.

1.7. 함수

  • MOD 함수
10 % 3 -> 1    
MOD(10,3) -> 1    
  • MOD함수를 사용하면 나머지를 쉽게 구할 수 있습니다.
  • MOD() 함수는 함수명이 MOD, 인수로 (나누어질 수, 나눌 수)의 형태를 띄게 됩니다.

예) MOD(10,3)

1.8. ROUND 함수

  • 부가세나 부가세포함된 금액을 계산할 때 어떤 함수를 사용하면 좋을까요?
  • ROUND()함수를 사용하면 단위를 고려한 반올림 처리를 손쉽게 할 수 있습니다.
select * from sample341;    
select amount, ROUND(amount) from sample341;    
  • INTEGER형: 정수만 저장 가능 amount열은 DECIMAL형으로 정의되었습니다.
  • DECIMAL형은 정수부와 소수부의 자릿수를 지정할 수 있는 자료형입니다. 즉, 소수점을 포함하는 수치를 저장하는 자료형이 됩니다.
  • ROUND함수는 소수점 첫째 자리 기준으로 반올림 한 값을 반환합니다. 함수의 두번째 인수로 반올림할 자릿수를 지정할 수도 있습니다.

단, 인수를 생략할 경우 0으로 간주되고 첫째 자리를 반올림합니다. 1을 지정하면 소수점 둘째 자리를 반올림합니다.

  • 음수의 경우는 어떻게 할 수 있을까요?

-1 지정시 1단위 , -2을 지정하면 10단위반올림할 수 있습니다.

select amount, ROUND(amount,-2) from sample341;    

인수에 -2를 입력하였으니 10단위를 반올림합니다. 예) 5961.69 → 6000(10단위 반올림)

  • 버림 함수는 어떤것이 있을까요?

반올림 이외에도 버림을 할 경우가 생길 수 있는데 TRUNCATE() 함수로 계산이 가능합니다.

  • 그 외 함수
  • SIN, COS 삼각함수
  • SQRT 루트를 계산하는 함수
  • LOG 대수를 계산하는 함수