#算术运算符
YashanDB提供如下算术运算符:
运算符 | 操作数 | 含义 | NULL参与运算 |
---|---|---|---|
+ | 一元/二元 | 一元表示正数,二元表示加法 | 结果为NULL |
- | 一元/二元 | 一元表示负数,二元表示减法 | 结果为NULL |
* | 二元 | 乘法 | 结果为NULL |
/ | 二元 | 普通除法 | 结果为NULL |
% | 二元 | 整数除法,返回余数 | 结果为NULL |
# 除法
YashanDB中,可实现除法运算的方式有:
%
取模运算,与MOD函数同义。
格式为:n2 % n1
含义为:将n2 整除n1后剩余的数值作为取模的结果,即余数,余数的正负符号与n2一致。
若n1为0,不报错,而是直接将n2的值作为余数结果返回。
/
普通除法运算。
/与DIV的关系:
- 对于小数(FLOAT/DOUBLE/NUMBER),/与DIV算法一致。
- 对于整数,/作普通除法运算,DIV作整除运算并返回商数。
一般情况下,在/或DIV运算里0不能作为除数,否则报错,但是在被除数是浮点数的情况下,不报错而是做如下特殊处理:
- 如果被除数是Nan,计算结果为Nan
- 如果被除数是正浮点数或Inf,计算结果为Inf
- 如果被除数是负浮点数或-Inf,计算结果为-Inf
# 运算优先级
从高到低的运算优先级为:+(取正)、-(取负)>*、/、%>+、-。同一优先级运算符从左向右执行。
可以使用双括号()来调整想达到的运算优先级。
# 数据类型
如下数据类型可能会参与到算术运算中:
数值型(除BIT外)
字符型
日期型
# 类型转换
在进行二元算术运算时,YashanDB将通过隐式数据转换,将参与运算的数据类型统一到某个数据类型,统一原则为:
- 数值型加、减、乘法最小提升规则:按TINYINT->SMALLINT->INT->BIGINT->NUMBER->FLOAT->DOUBLE顺序向后统一。
- 数值型除法最小提升规则:按TINYINT/SMALLINT/INT/BIGINT->NUMBER->FLOAT->DOUBLE顺序向后统一。
- 字符型向数值型类型统一。
- 数值型、字符型向日期型统一。
# (1)整型数值之间统一规则
行列标题格为参与算术运算的数据类型;内容单元格为统一后的数据类型;–表示不支持两种数据类型参与算术运算。
数据类型 | 运算符or函数 | TINYINT | SMALLINT | INT | BIGINT* |
---|---|---|---|---|---|
TINYINT | +、-、* | SMALLINT | INT | BIGINT | BIGINT/NUMBER |
/ | NUMBER | NUMBER | NUMBER | NUMBER | |
%、MOD、DIV | SMALLINT | INT | BIGINT | BIGINT/NUMBER | |
SMALLINT | +、-、* | INT | INT | BIGINT | BIGINT/NUMBER |
/ | NUMBER | NUMBER | NUMBER | NUMBER | |
%、MOD、DIV | INT | INT | BIGINT | BIGINT/NUMBER | |
INT | +、-、* | BIGINT | BIGINT | BIGINT | BIGINT/NUMBER |
/ | NUMBER | NUMBER | NUMBER | NUMBER | |
%、MOD、DIV | BIGINT | BIGINT | BIGINT | BIGINT/NUMBER | |
BIGINT* | +、-、* | BIGINT/NUMBER | BIGINT/NUMBER | BIGINT/NUMBER | BIGINT/NUMBER |
/ | NUMBER | NUMBER | NUMBER | NUMBER | |
%、MOD、DIV | BIGINT/NUMBER | BIGINT/NUMBER | BIGINT/NUMBER | BIGINT/NUMBER |
Note:
BIGINT类型与所有整数类型参与+、-、*、%、MOD、DIV算术运算,或者对BIGINT类型作取负(-)运算时:
- _PROMOTE_NUMBER(隐藏参数,默认值
FALSE
)=true:数据类型统一转换为NUMBER- _PROMOTE_NUMBER(隐藏参数,默认值
FALSE
)=false:数据类型统一转换为BIGINT
# (2)整型数值与其他数值之间统一规则
行列标题格为参与算术运算的数据类型;内容单元格为统一后的数据类型,其中(1)表示采用上面(1)整型数值之间统一规则;–表示不支持两种数据类型参与算术运算。
数据类型 | 运算符or函数 | 整型数值 | NUMBER | FLOAT | DOUBLE |
---|---|---|---|---|---|
整型数值 | +、-、* | (1) | NUMEBR | FLOAT | DOUBLE |
/ | (1) | NUMEBR | FLOAT | DOUBLE | |
%、MOD、DIV | (1) | NUMEBR | FLOAT | DOUBLE | |
NUMBER | +、-、* | NUMEBR | NUMBER | FLOAT | DOUBLE |
/ | NUMEBR | NUMEBR | FLOAT | DOUBLE | |
%、MOD、DIV | NUMEBR | NUMEBR | FLOAT | DOUBLE | |
FLOAT | +、-、* | FLOAT | FLOAT | FLOAT | DOUBLE |
/ | FLOAT | FLOAT | FLOAT | DOUBLE | |
%、MOD、DIV | FLOAT | FLOAT | FLOAT | DOUBLE | |
DOUBLE | +、-、* | DOUBLE | DOUBLE | DOUBLE | DOUBLE |
/ | DOUBLE | DOUBLE | DOUBLE | DOUBLE | |
%、MOD、DIV | DOUBLE | DOUBLE | DOUBLE | DOUBLE |
# (3)数值型与字符型统一规则
行列标题格为参与算术运算的数据类型;内容单元格为统一后的数据类型,其中(2)表示采用上面(2)整型数值与其他数值之间统一规则;–表示不支持两种数据类型参与算术运算。
数据类型 | 运算符or函数 | 整型数值 | NUMBER | FLOAT | DOUBLE | 字符型 |
---|---|---|---|---|---|---|
整型数值 | +、-、*、/、%、MOD、DIV | (2) | (2) | (2) | (2) | NUMEBR |
NUMBER | +、-、*、/、%、MOD、DIV | (2) | (2) | (2) | (2) | NUMBER |
FLOAT | +、-、*、/、%、MOD、DIV | (2) | (2) | (2) | (2) | FLOAT |
DOUBLE | +、-、*、/、%、MOD、DIV | (2) | (2) | (2) | (2) | DOUBLE |
字符型 | +、-、*、/、%、MOD、DIV | NUMBER | NUMEBR | FLOAT | DOUBLE | NUMEBR |
# (4)数值型、字符型与日期型统一规则
行列标题格为参与算术运算的数据类型;内容单元格为统一后的数据类型,其中(3)表示采用上面(3)数值型与字符型统一规则;–表示不支持两种数据类型参与算术运算;YM表示INTERVAL YEAR TO MONTH,DS表示INTERVAL DAY TO SECOND,TS表示TIMESTAMP。
数据类型 | 运算符 | 数值型 | 字符型 | TIME | DATE | TS | YM | DS |
---|---|---|---|---|---|---|---|---|
数值型 | + | (3) | (3) | -- | DATE | DATE | -- | -- |
- | (3) | (3) | -- | -- | -- | -- | -- | |
* | (3) | (3) | -- | -- | -- | YM | DS | |
/ | (3) | (3) | -- | -- | -- | -- | -- | |
字符型 | +、- | (3) | (3) | -- | DATE | DATE | -- | -- |
*、/ | (3) | (3) | -- | -- | -- | YM | DS | |
TIME | + | -- | -- | -- | TS | TS | -- | TIME |
- | -- | -- | DS | -- | -- | -- | TIME | |
DATE | + | DATE | DATE | TS | -- | -- | DATE | DATE |
- | DATE | DATE | TS | NUMBER | DS | DATE | DATE | |
TS | + | DATE | DATE | TS | -- | -- | TS | TS |
- | DATE | DATE | TS | DS | DS | TS | TS | |
YM | + | -- | -- | -- | DATE | TS | YM | -- |
- | -- | -- | -- | -- | -- | YM | -- | |
* | YM | YM | -- | -- | -- | -- | ||
/ | YM | YM | -- | -- | -- | -- | ||
DS | + | -- | -- | TIME | DATE | TS | DS | -- |
- | -- | -- | -- | -- | -- | DS | -- | |
* | DS | DS | -- | -- | -- | -- | -- | |
/ | DS | DS | -- | -- | -- | -- | -- |
示例
--字符型与数值型运算时,将字符型转换为NUMBER类型后参与计算
SELECT '44'/2 char_cal,
TYPEOF('44'/2) type_trans
FROM dual;
CHAR_CAL TYPE_TRANS
----------- ----------
22 number
--INT类型与FLOAT类型计算时,将INT类型转换为FLOAT类型参与计算
SELECT 2*CAST(2 AS FLOAT) int_cal,
TYPEOF(2*CAST(2 AS FLOAT)) type_trans
FROM dual;
INT_CAL TYPE_TRANS
----------- ----------------------------------------------------------------
4.0E+000 float
# 日期型算术运算
日期型数据可参与如下算术运算:
运算符 | 操作数 | 返回类型 | 运算规则 |
---|---|---|---|
+ | 二元 | * 时间 | * 将两个间隔类型相加,返回更长的间隔类型。 * 将DATE、TIMESTAMP与TIME类型相加,返回在时间轴上更靠后的TIMESTAMP。 * 将TIME、DATE、TIMESTAMP与间隔类型相加,返回在时间轴上更靠后的TIME、DATE、TIMESTAMP。 * 将DATE、TIMESTAMP与数值相加,数值被解释为天数(小数部分表示不满一天的时间),返回在时间轴上更靠后的DATE。 |
- | 二元 | * 时间间隔 * 时间 | * 将两个间隔类型相减,返回更短的间隔类型。 * 将DATE、TIMESTAMP与TIME相减,返回在时间轴上更靠前的TIMESTAMP。 * 将两个DATE相减,返回数值,表示相差的天数。 * 将DATE与TIMESTAMP相减,或TIMESTAMP与TIMESTAMP相减,返回DS_INTERVAL。 * 将DATE或TIMESTAMP与数值相减,数值被解释为天数(小数部分表示不满一天的时间),返回在时间轴上更靠前的DATE。 |
* | 二元 | * 时间间隔 * 时间 | * 将间隔类型与数值相乘,返回被扩大倍数的间隔。 |
/ | 二元 | * 时间间隔 * 时间 | * 将间隔类型除以数值,返回被缩小倍数的间隔。 |
如下是时间类型和时间间隔类型支持运算的详细情况,其中YM表示INTERVAL YEAR TO MONTH,DS表示INTERVAL DAY TO SECOND,TS表示TIMESTAMP:
数据类型 | NUMBER | TIME | DS | YM | DATE | TS |
---|---|---|---|---|---|---|
TIME | N/A | 支持运算:- 返回类型:DS | 支持运算:+- 返回类型:TIME | N/A | 支持运算:+ 返回类型:TS | 支持运算:+ 返回类型:TS |
DS | 支持运算:*/ 返回类型:DS | 支持运算:+ 返回类型:TIME | 支持运算:+- 返回类型:DS | N/A | 支持运算:+ 返回类型:DATE | 支持运算:+ 返回类型:TS |
YM | 支持运算:*/ 返回类型:YM | N/A | N/A | 支持运算:+- 返回类型:YM | 支持运算:+ 返回类型:DATE | 支持运算:+ 返回类型:TS |
DATE | 支持运算:+- 返回类型:DATE | 支持运算:+- 返回类型:TS | 支持运算:+- 返回类型:DATE | 支持运算:+- 返回类型:DATE | 支持运算:- 返回类型:NUMBER | 支持运算:- 返回类型:DS |
TS | 支持运算:+- 返回类型:DATE | 支持运算:+- 返回类型:TS | 支持运算:+- 返回类型:TS | 支持运算:+- 返回类型:TS | 支持运算:- 返回类型:DS | 支持运算:- 返回类型:DS |
示例
CREATE TABLE date_dd(a DATE, b DATE);
INSERT INTO date_dd VALUES('2008-12-31','2018-12-31');
COMMIT;
--运算符 '-' 返回时间间隔
SELECT b-a FROM date_dd;
B-A
-----------
3652
--运算符 '-' 返回时间
SELECT b-1 FROM date_dd;
B-1
--------------------------------
2018-12-30 00:00:00
SELECT SYSDATE+2 FROM DUAL;
SYSDATE+2
--------------------------------
2021-06-10 11:07:47
-- DATE和TIEMSTAMP与数值类型做加减运算,数值表示天
CREATE TABLE date_dt(c1 DATE, c2 TIMESTAMP);
INSERT INTO date_dt VALUES ('2020-03-31', '2020-03-31 12:30:59.999999');
COMMIT;
SELECT c1-2.5, c2-2.5 FROM date_dt;
C1-2.5 C2-2.5
-------------------------------- --------------------------------
2020-03-28 12:00:00 2020-03-29 00:30:59
SELECT c1+'2.5', c2+'2.5' FROM date_dt;
C1+'2.5' C2+'2.5'
-------------------------------- --------------------------------
2020-04-02 12:00:00 2020-04-03 00:30:59
SELECT c1 FROM date_dt;
C1
--------------------------------
2020-03-31 00:00:00
-- 输出结果为TIME类型的运算
CREATE TABLE date_t(c1 TIME);
INSERT INTO date_t VALUES ('23:59:59.999999');
COMMIT;
SELECT c1+INTERVAL '5' HOUR FROM date_t;
C1+INTERVAL'5'HOUR
--------------------
04:59:59.999999
输出的日期如果不合法,结果会报错。
示例
--对上例data_dt中的字段执行下面的运算,结果为4月31日,该日期不合法
SELECT C1+INTERVAL '01-01' YEAR TO MONTH FROM date_dt;
--行存表输出
YAS-00008 type convert error : not a valid month
--列存表输出
YAS-05012 date not valid for month specified