日期和时间型

DATE

DATE类型存储年月日信息。

语法

​ DATE的常量值可以使用解释文本、DATE类型注释的字符串文本或者可以强制类型转DATE类型来表示。InCloud ZNBASE还支持在需要DATE的上下文中使用未解释的字符串。

​ 日期的字符串格式为YYYY-MM-DD。例如:DATE ‘2016-12-23’。

​ DATE支持最大宽度为16个字节,但由于ZNBASE元数据,总存储大小可能会更大。

类型转换

DATE类型可以强制转换为以下任何数据类型:

类型描述
DECINAL转换为自Unix时代(1970年1月1日)以来的天数。
FLOAT转换为自Unix时代(1970年1月1日)以来的天数。
INT转换为自Unix时代(1970年1月1日)以来的天数。
TIMESTAMP将结果时间戳记中的时间设置为00:00(午夜)。
STRING—-
示例

示例1:创建一个表dates:

CREATE TABLE dates (a DATE PRIMARY KEY, b INT);

SHOW COLUMNS FROM dates;

column_name | data_type | is_nullable | column_default | generation_expression | indices | is_hidden

+——————-+—————-+——————-+————————+———————————-+—————-+—————-+

a | DATE | false | NULL | | {primary} | false

b | INT | true | NULL | | {} | false (2 rows) |

示例2:显示插入DATE:

INSERT INTO dates VALUES (DATE ‘2016-03-26’, 12345);

INSERT 1

SELECT * FROM dates;

a | b

+—————————————-+———-+

2016-03-26 00:00:00+00:00 | 12345

示例3:使用字符串来隐式插入DATE:

INSERT INTO dates VALUES (‘2016-03-27’, 12345);

SELECT * FROM dates;

a | b

+—————————————-+———-+

2016-03-26 00:00:00+00:00 | 12345

2016-03-27 00:00:00+00:00 | 12345

TIME

​ TIME存储没有时区的时间。

别名

​ 在InCloud ZNBASE中,TIME的别名是TIME WITHOUT TIME ZONE。

语法

​ TIME的常量值可以使用解释文本、类型TIME注释的字符串文本,或者强制类型转换为类型TIME来表示。ZNBASE还支持在预期TIME值的上下文中使用未解释的字符串文本。

​ 时间的字符串格式是HH:MM:SS.SSSSSS。 例如:TIME’05:40:00.000001’。TIME的小数部分是可选的,并且四舍五入到微秒(即小数点后的六位数)。

​ TIME支持最大宽度为8个字节,由于InCloud ZNBASE元数据,总存储大小可能会更大。

类型转换

TIME值可以强制转换为以下任何数据类型:

类型描述
INTERVAL转换为午夜(00:00)以来的时间跨度
STRING转换为格式’HH:MM:SS.SSSSSS’(微秒)
示例

示例1:使用TIME创建表time:

CREATE TABLE time (time_id INT PRIMARY KEY, time_val TIME);

SHOW COLUMNS FROM time;

column_name | data_type | is_nullable | column_default | generation_expression | indices | is_hidden

+——————-+—————-+——————-+————————+———————————-+—————-+—————-+

time_id | INT | false | NULL | | {primary} | false

time_val | TIME | true | NULL | | {} |

false (2 rows)

INSERT INTO time VALUES (1, TIME ‘05:40:00’), (2, TIME ‘05:41:39’);

SELECT * FROM time;

time_id | time_val

+————-+—————————————-+

1 | 0000-01-01 05:40:00+00:00

2 | 0000-01-01 05:41:39+00:00 |

示例2:将TIME类型的字段插入表中:

INSERT INTO time VALUES (1, TIME ‘05:40:00’), (2, TIME ‘05:41:39’);

SELECT * FROM time;

time_id | time_val

+————-+———————————————-+

1 | 0000-01-01 05:40:00+00:00

2 | 0000-01-01 05:41:39+00:00

示例3:比较TIME类型的值:

SELECT (SELECT time_val FROM time WHERE time_id = 1) < (SELECT time_val FROM time WHERE time_id = 2);

?column?

+—————+

true

TIMESTAMP与TIMESTAMPTZ

别名

​ 在InCloud ZNBASE中,TIMESTAMP的别名是TIMESTAMP WITHOUT TIMEZONE;TIMESTAMPTZ的别名是TIMESTAMP WITH TIME ZONE。

语法

TIMESTAMP和TIMESTAMPTZ以UTC格式存储日期和时间。

  • TIMESTAMP以UTC 表示所有值。

  • TIMESTAMPTZ将TIMESTAMP值从UTC转换为客户端的会话时区(除非为该值指定了另一个时区)。但是, TIMESTAMPTZ不存储任何时区数据。

​ 这两种类型之间的区别在于TIMESTAMPTZ使用客户端的会话时区,而另一种则不然。因此,建议始终使用TIMESTAMPTZ,因为当TIMESTAMP变体忽略会话偏移量时,有时会导致意外行为。

​ 类型为TIMESTAMP/TIMESTAMPTZ的常量值可以使用解释后的文字来表示,也可以使用类型为TIMESTAMP/TIMESTAMPTZ注释的字符串文字来表示,也可以强制类型为TIMESTAMP/TIMESTAMPTZ。

TIMESTAMP常量可以使用以下字符串文字格式表示:

格式示例
仅显示日期TIMESTAMP ‘2016-01-25’
显示日期和时间TIMESTAMP ‘2016-01-25 10:10:10.555555’
ISO 8601TIMESTAMP ‘2016-01-25T10:10:10.555555’

​ 请使用以下格式:TIMESTAMPTZ’2016-01-2510:10:10.555555-05:00’,来表示TIMESTAMPTZ值(包括UTC的时区偏移)。如果明确,则简单的无注释的字符串文字也可以自动解释为类型TIMESTAMP或TIMESTAMPTZ类型。

​ 请注意,小数部分是可选的,并且四舍五入到微秒(十进制后的6位数)。

​ TIMESTAMP列支持最大12个字节宽度的值,但由于ZNBASE元数据因素,总存储大小可能更大。

类型转换

TIMESTAMP 可以被转换为以下数据类型:

类型描述
DECINAL转换为自Unix时代(1970年1月1日)以来的天数。
FLOAT转换为自Unix时代(1970年1月1日)以来的天数。
INT转换为自Unix时代(1970年1月1日)以来的天数。
TIME转换为时间戳记的时间部分(HH:MM:SS)
TIMESTAMP将结果时间戳记中的时间设置为00:00(午夜)。
DATE—-
STRING—-
示例

示例1:使用TIMESTAMPTZ创建表timestamps:

CREATE TABLE timestamps (c1 INT PRIMARY KEY, c2 TIMESTAMP, c3 TIMESTAMPTZ);

CREATE TABLE

SHOW COLUMNS FROM timestamps;

column_name | data_type | is_nullable | column_default | generation_expression | indices | is_hidden

+——————-+—————-+——————-+————————+———————————-+—————-+—————-+

c1 | INT | false | NULL | | {primary} | false

c2 | TIMESTAMP | true | NULL | | {} | false

c3 | TIMESTAMPTZ | true | NULL | | {} | false

示例2:将TIMESTAMPTZ类型的字段插入表timestamps:

INSERT INTO timestamps VALUES(1, TIMESTAMP ‘2016-03-26’, TIMESTAMPTZ ‘2016-03-26 10:10:10-05:00’);

INSERT 1

SELECT * FROM timestamps;

c1 | c2 | c3

+——+—————————————-+—————————————-+

1 | 2016-03-26 00:00:00+00:00 | 2016-03-26 15:10:10+00:00

ON UPDATE CURRENT_TIMESTAMP子句

​ CURRENT_TIMESTAMP表示当前的时间戳。

​ 对于任何表中TIMESTAMP类型的字段,可以把CURRENT_TIMESTAMP作为其默认值,也可以把自动更新的CURRENT_TIMESTAMP设置为其值,这时需要使用ON UPDATE CURRENT_TIMESTAMP子句。

​ 当使用ON UPDATE CURRENT_TIMESTAMP子句时,在表中内容更新时,会将timestamp字段的内容更新为当前时间点;当不使用该子句时,在表中内容更新时表,不会更新时间戳的值。

​ 在不使用ON UPDATE CURRENT_TIMESTAMP子句的情况下,当表中的内容更新时,timestamp字段的内容不更新。

创建test1,将CURRENT_TIMESTAMP设为timestamp的默认值

create table test1(id int, expire_time timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP);

CREATE TABLE

向表中插入行数据:

insert into test1 values(1);

select * from test1;

id | expire_time

-—+——————————————

1 | 2020-06-17 06:44:25.348651

insert into test1 values(2);

select * from test1;

id | expire_time

-—+——————————————

1 | 2020-06-17 06:44:25.348651

2 | 2020-06-17 06:46:12.196118

更新表中的数据

update test1 set id=100 where id=2;

select * from test1;

id | expire_time

-—-+——————————————

1 | 2020-06-17 06:44:25.348651

100 | 2020-06-17 06:46:12.196118

表第2行的时间戳没有变化

在使用ON UPDATE CURRENT_TIMESTAMP子句的情况下,当表中内容更新时,timestamp字段的内容会更新为当前的时间戳。

创建test2,将CURRENT_TIMESTAMP设为timestamp的默认值,并使用ON UPDATE CURRENT_TIMESTAMP子句

create table test2( id int, expire_time timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP);

CREATE TABLE

向表中插入一行数据:

insert into test2 values(1);

select * from test1;

id | expire_time

-—+——————————————

1 | 2020-06-17 07:12:32.503519

向表中再插入一行数据:

insert into test2 values(2);

select * from test2;

id | expire_time

-—+——————————————

1 | 2020-06-17 07:12:32.503519

2 | 2020-06-17 07:13:14.767218

更新表中的数据

update test1 set id=100 where id=2;

select * from test1;

id | expire_time

-—-+——————————————

1 | 2020-06-17 07:12:32.503519

100 | 2020-06-17 07:14:30.718073

表第2行的时间戳没有发生变化

INTERVAL

INTERVAL数据类型存储表示时间跨度的值。

语法

​ INTERVAL的常量值可以使用解释文本( interpretedliteral)、类型INTERVAL注释的字符串文本,或者强制类型转换为类型INTERVAL来表示;InCloudZNBASE还支持在预期会有值的上下文中使用未解释的INTERVAL字符串文字。

INTERVAL常量可以使用以下格式表示:

  • SQL标准:INTERVAL ‘Y-M D H:M:S’

Y-M D:使用单个值仅定义天数; 使用两个值定义年份和月份。值必须是整数。
H:M:S:使用单个值仅定义秒; 使用两个值定义小时和分钟。值可以是整数或浮点数。注意:每一项都是可选的。

  • ISO 8601标准:INTERVAL ‘P1Y2M3DT4H5M6S’
大小和精度

​ INTERVAL列支持宽度最多24个字节的值,但由于InCloud ZNBASE元数据因素,总存储大小可能更大。INTERVAL的数据类型在内部存储为月,日和微秒。

​ INTERVAL以微秒精度而不是纳秒存储。因此,从字符串中解析或从浮点数或十进制转换得到的数据将舍入到最接近的微秒,INTERVAL上的任何算术运算(加,减,乘,除)也将舍入。InCloudZNBASE采用四舍五入而不是截断的方式来进行舍入。

类型转换

INTERVAL可以转换为以下任何数据类型:

类型描述
DECINAL转换为自Unix时代(1970年1月1日)以来的天数。
FLOAT转换为自Unix时代(1970年1月1日)以来的天数。
INT转换为自Unix时代(1970年1月1日)以来的天数。
TIME转换为时间戳记的时间部分(HH:MM:SS)
示例

示例1:使用INTERVAL创建表intervals:

CREATE TABLE intervals (c1 INT PRIMARY KEY, c2 INTERVAL);

CREATE TABLE

SHOW COLUMNS FROM intervals;

column_name | data_type | is_nullable | column_default | generation_expression | indices | is_hidden

+——————-+—————-+——————-+————————+———————————-+—————-+—————-+

c1 | INT | false | NULL | | {primary} | false

c2 | INTERVAL | true | NULL | | {} | false

注意:如果将INTERVAL用作主键,则可能会导致唯一性问题。

示例2:将INTERVAL类型的字段插入表intervals:

INSERT INTO intervals VALUES (1, INTERVAL ‘1 year 2 months 3 days 4 hours 5 minutes 6 seconds’),(2, INTERVAL ‘1-2 3 4:5:6’),(3, ‘1-2 3 4:5:6’);

INSERT 3

SELECT * FROM intervals;

c1 | c2 +——+———————————————-+

1 | 1 year 2 mons 3 days 04:05:06

2 | 1 year 2 mons 3 days 04:05:06

3 | 1 year 2 mons 3 days 04:05:06 |