这是本节的多页打印视图。 点击此处打印.

返回本页常规视图.

INTERVAL

表示两个时间点之间的时间差。间隔可以是正,也可以是负。INTERVAL 数据类型符合 SQL:2008 标准,并支持拆分为两个主要子类型的间隔限定符

  • 年-月:年和月的时间范围

  • 天-时间:以天、小时、分钟、秒以及毫秒为单位的时间跨度

间隔在内部表示为若干微秒,印刷为多达 60 秒钟、60 分钟、24 小时、30 天、12 个月,以及需要的年数。您可以使用 SET INTERVALSTYLESET DATESTYLE控制间隔单位的输出格式

语法

INTERVAL 'interval-literal' [ interval-qualifier ] [ (p) ]

参数

限制

1 - 设置间隔单位显示

SET INTERVALSTYLESET DATESTYLE 控制间隔单位的输出格式。

省略间隔单位

要从输出中省略间隔单位,请将 INTERVALSTYLE 设置为 PLAIN。这是默认设置,符合 SQL:2008 标准:

=> SET INTERVALSTYLE TO PLAIN;
SET
=> SELECT INTERVAL '3 2';
?column?
----------
 3 02:00

INTERVALSTYLE 设置为 PLAIN 时,输出中会省略单位,即使查询指定了输入单位:

=> SELECT INTERVAL '3 days 2 hours';
 ?column?
----------
 3 02:00

如果 DATESTYLE 设置为 SQL,则 Vertica 符合 SQL:2008 标准,并始终从输出中省略间隔单位:


=> SET DATESTYLE TO SQL;
SET
=> SET INTERVALSTYLE TO UNITS;
SET
=> SELECT INTERVAL '3 2';
 ?column?
----------
 3 02:00

显示间隔单位

要启用间隔单位的显示,必须将 DATESTYLE 设置为 ISO。然后,您可以通过将 INTERVALSTYLE 设置为 UNITS 来显示间隔单位:


=> SET DATESTYLE TO ISO;
SET
=> SET INTERVALSTYLE TO UNITS;
SET
=> SELECT INTERVAL '3 2';
 ?column?
----------------
 3 days 2 hours

检查 INTERVALSTYLE 和 DATESTYLE 设置

使用 SHOW 语句检查 INTERVALSTYLEDATESTYLE 设置:

=> SHOW INTERVALSTYLE;
     name      | setting
---------------+---------
 intervalstyle | units
=> SHOW DATESTYLE;
   name    | setting
-----------+----------
 datestyle | ISO, MDY

2 - 指定间隔输入

间隔值通过字面量类时间间隔表示。字面量类时间间隔由一个或多个间隔字段组成,其中每个字段代表天和时间或年和月的时间范围,如下所示:

[-] { quantity subtype-unit }[...] [AGO]

使用子类型单位

子类型单位对于天-时间间隔是可选的;而对于年-月间隔则必须指定。

例如,下面的第一个语句隐式指定了天和时间;第二个语句显式标识天和时间单位。两个语句都返回相同的结果:


=> SET INTERVALSTYLE TO UNITS;
=> SELECT INTERVAL '1 12:59:10:05';
      ?column?
--------------------
 1 day 12:59:10.005
(1 row)

=> SELECT INTERVAL '1 day 12 hours 59 min 10 sec 5 milliseconds';
      ?column?
--------------------
 1 day 12:59:10.005
(1 row)

以下两个语句分别将 28 天和 4 周添加到当前日期。两种情况下的间隔相等,并且语句返回相同的结果。但是,在第一个语句中,字面量类时间间隔省略了子类型(隐式 days);在第二个语句中,字面量类时间间隔必须包含子类型单位 weeks

=> SELECT CURRENT_DATE;
  ?column?
------------
 2016-08-15
(1 row)

=> SELECT CURRENT_DATE + INTERVAL '28';
      ?column?
---------------------
 2016-09-12 00:00:00
(1 row)

dbadmin=> SELECT CURRENT_DATE + INTERVAL '4 weeks';
      ?column?
---------------------
 2016-09-12 00:00:00
(1 row)

字面量类时间间隔可以包括天-时间和年-月字段。例如,以下语句将 4 年、4 周、4 天和 14 小时的间隔添加到当前日期。年和周字段必须包含子类型单位;天和小时字段则将其省略:

> SELECT CURRENT_DATE + INTERVAL '4 years 4 weeks 4 14';
      ?column?
---------------------
 2020-09-15 14:00:00
(1 row)

省略子类型单位

您可以指定天、小时、分钟和秒的数量,无需指定单位。Vertica 将字面量类时间间隔中的冒号识别为时间戳的一部分:

=> SELECT INTERVAL '1 4 5 6';
 ?column?
------------
 1 day 04:05:06
=> SELECT INTERVAL '1 4:5:6';
 ?column?
------------
 1 day 04:05:06
=> SELECT INTERVAL '1 day 4 hour 5 min 6 sec';
 ?column?
------------
 1 day 04:05:06

如果 Vertica 无法确定单位,它会根据间隔限定符将该数量应用于缺失单位。在接下来的两个示例中,Vertica 使用默认间隔限定符 (DAY TO SECOND(6)) 并将尾数 1 分配给天,因为它已经在输出中处理了小时、分钟和秒:

=> SELECT INTERVAL '4:5:6 1';
 ?column?
------------
 1 day 04:05:06
=> SELECT INTERVAL '1 4:5:6';
 ?column?
------------
 1 day 04:05:06

在接下来的两个示例中,Vertica 将 4:5 识别为 hours:minutes。将字面量类时间间隔中的剩余值分配给缺失单位: 1 分配给天,而 2 分配给秒。

SELECT INTERVAL '4:5 1 2';
  ?column?
------------
 1 day 04:05:02
=> SELECT INTERVAL '1 4:5 2';
 ?column?
------------
 1 day 04:05:02

指定间隔限定符可以改变 Vertica 解释 4:5 的方式:

=> SELECT INTERVAL '4:5' MINUTE TO SECOND;
  ?column?
------------
 00:04:05

3 - 控制间隔格式

间隔限定符指定 Vertica 用来解释和格式化字面量类时间间隔的一系列选项。间隔限定符也可以指定精度。每个间隔限定符由一个或两个单位组成:

unit[p] [ TO unit[p] ]

其中:

  • 单位指定天-时间或年-月子类型

  • p 指定精度,0 到 6 之间的整数。通常,精度仅适用于 SECOND 单位。SECOND 的默认精度为 6。有关详细信息,请参阅指定时间间隔精度

如果间隔省略了间隔限定符,Vertica 将使用默认值 DAY TO SECOND(6)

间隔限定符类别

间隔限定符属于以下类别之一:

  • 年-月:年和月的时间范围

  • 天-时间:以天、小时、分钟、秒以及毫秒为单位的时间跨度

年-月

Vertica 支持两种年-月子类型: YEARMONTH

在以下示例中,YEAR TO MONTH 限定字面量类时间间隔 1 2 以指示时间范围为 1 年零两个月:

=> SELECT interval '1 2' YEAR TO MONTH;
 ?column?
----------
 1-2
(1 row)

如果省略限定符,Vertica 将使用默认间隔限定符 DAY TO SECOND 并返回不同的结果:

=> SELECT interval '1 2';
 ?column?
----------
 1 02:00
(1 row)

以下示例使用间隔限定符 YEAR。在这种情况下,Vertica 仅从字面量类时间间隔 1y 10m 中提取年份:

=> SELECT INTERVAL '1y 10m' YEAR;
 ?column?
----------
 1
(1 row)

在下一个示例中,间隔限定符 MONTH 将相同的字面量类时间间隔转换为月份:

=> SELECT INTERVAL '1y 10m' MONTH;
 ?column?
----------
 22
(1 row)

天-时间

Vertica 支持四种天-时间子类型:DAYHOURMINUTESECOND

在以下示例中,间隔限定符 DAY TO SECOND(4) 限定字面量类时间间隔 1h 3m 6s 5msecs 57us。限定符还将秒的精度设置为 4:

=> SELECT INTERVAL '1h 3m 6s 5msecs 57us' DAY TO SECOND(4);
   ?column?
---------------
 01:03:06.0051
(1 row)

如果未指定间隔限定符,则 Vertica 将使用默认子类型 DAY TO SECOND(6),无论您如何指定字面量类时间间隔。例如,作为 SQL:2008 的扩展,以下两个命令都将返回 91days

=> SELECT INTERVAL '2-6';
    ?column?
-----------------
 910
=> SELECT INTERVAL '2 years 6 months';
 ?column?
-----------------
 910

间隔限定符可以从输入参数中提取其他值。例如,以下命令从字面量类时间间隔 3 days 2 hours 中提取 HOUR 值:

=> SELECT INTERVAL '3 days 2 hours' HOUR;
 ?column?
----------
 74

主要的天/时间 (DAY TO SECOND) 和年/月 (YEAR TO MONTH) 子类型范围可以通过间隔限定符限制为更具体的类型范围。例如,HOUR TO MINUTE 是天/时间间隔的有限形式,可用于表示时区偏移量。

=> SELECT INTERVAL '1 3' HOUR to MINUTE;
 ?column?
---------------
 01:03

hh:mm:sshh:mm 格式仅在间隔限定符中指定的至少两个字段非零且不超过 23 小时或 59 分钟时使用:

=> SELECT INTERVAL '2 days 12 hours 15 mins' DAY TO MINUTE;
  ?column?
--------------
 2 12:15
=> SELECT INTERVAL '15 mins 20 sec' MINUTE TO SECOND;
 ?column?
----------
 15:20
=> SELECT INTERVAL '1 hour 15 mins 20 sec' MINUTE TO SECOND;
 ?column?
-----------------
 75:20

4 - 指定时间间隔精度

通常,时间间隔精度仅适用于秒。如果未明确指定精度,则 Vertica 将精度四舍五入到最多六位小数。例如:

=> SELECT INTERVAL '2 hours 4 minutes 3.709384766 seconds' DAY TO SECOND;
    ?column?
-----------------
 02:04:03.709385
(1 row)

Vertica 允许您通过两种方式指定时间间隔精度:

  • INTERVAL 关键字之后

  • 在时间间隔限定符的 SECOND 单元之后,指定以下之一:

    • DAY TO SECOND

    • HOUR TO SECOND

    • MINUTE TO SECOND

    • SECOND

例如,以下语句使用全部两种方法来设置精度,并返回相同的结果:

=> SELECT INTERVAL(4) '2 hours 4 minutes 3.709384766 seconds' DAY TO SECOND;
   ?column?
---------------
 02:04:03.7094
(1 row)

=> SELECT INTERVAL '2 hours 4 minutes 3.709384766 seconds' DAY TO SECOND(4);
   ?column?
---------------
 02:04:03.7094
(1 row)

如果同一语句多次指定精度,则 Vertica 使用较低的精度。例如,以下语句指定两次精度:INTERVAL 关键字指定精度 1,时间间隔限定符 SECOND 指定精度 2。Vertica 使用较低的精度 1:

=> SELECT INTERVAL(1) '1.2467' SECOND(2);
 ?column?
----------
 1.2 secs

设置时间间隔表列的精度

如果创建具有时间间隔列的表,则以下限制适用于列定义:

  • 仅当您不指定时间间隔限定符时,才能在 INTERVAL 关键字上设置精度。如果您尝试在 INTERVAL 关键字上设置精度并包含时间间隔限定符,则 Vertica 返回错误。

  • 您只能在时间间隔限定符的最后一个单元上设置精度。例如:

    CREATE TABLE public.testint2
    (
        i INTERVAL HOUR TO SECOND(3)
    );
    

    如果您在另一个单元上指定精度,Vertica 会在保存表定义时将其丢弃。

5 - 间隔单位的小数秒

Vertica 支持以毫秒为单位的时间间隔 (hh:mm:ss:ms),其中 01:02:03:25 表示 1 小时、2 分钟、3 秒和 025 毫秒。毫秒转换为小数秒,如下例所示,返回 1 天、2 小时、3 分钟、4 秒和 25.5 毫秒:

=> SELECT INTERVAL '1 02:03:04:25.5';
  ?column?
------------
 1 day 02:03:04.0255

Vertica 允许使用小数分钟。小数分钟四舍五入为秒:

=> SELECT INTERVAL '10.5 minutes';
  ?column?
------------
 00:10:30
=> select interval '10.659 minutes';
  ?column?
-------------
 00:10:39.54
=> select interval '10.3333333333333 minutes';
 ?column?
----------
 00:10:20

考量

  • INTERVAL 只能包含您需要的单位子集;但是,年/月间隔表示没有固定天数的日历年和月,因此年/月间隔值不能包括天、小时、分钟。当为天/时间间隔指定年/月值时,间隔扩展假定每月 30 天,每年 365 天。由于给定月份或年份的长度会有所不同,因此天/时间间隔永远不会以月或年的形式输出,而只会以天、小时、分钟等形式输出。

  • 天/时间和年/月间隔在逻辑上是相互独立的,不能相互组合或相互比较。在以下示例中,包含 DAYS 的字面量类时间间隔不能与 YEAR TO MONTH 类型组合:

    => SELECT INTERVAL '1 2 3' YEAR TO MONTH;
    ERROR 3679:  Invalid input syntax for interval year to month: "1 2 3"
    
  • Vertica 接受最多 2^63 – 1 微秒或月(约 18 位)的时间间隔。

  • INTERVAL YEAR TO MONTH 可在分析 RANGE 窗口中使用,其条件是当 ORDER BY 列类型为 TIMESTAMP/TIMESTAMP WITH TIMEZONEDATE 时。不支持使用 TIME/TIME WITH TIMEZONE

  • ORDER BY 列类型为 TIMESTAMP/TIMESTAMP WITH TIMEZONEDATETIME/TIME WITH TIMEZONE 时,您可以使用 INTERVAL DAY TO SECOND

示例

此部分中的示例假设 INTERVALSTYLE 设置为 PLAIN,因此结果省略了子类型单位。省略间隔限定符的间隔值使用默认值 DAY TO SECOND(6)

6 - 处理带符号的间隔

在 SQL:2008 标准中,字面量类时间间隔前的减号或作为字面量类时间间隔的第一个字符的减号会整个字面量为负,而不仅仅是第一个组件。在 Vertica 中,前导减号会使整个间隔为负,而不仅仅是第一个组件。以下命令都返回相同的值:

=> SELECT INTERVAL '-1 month - 1 second';
 ?column?
----------
 -29 days 23:59:59

=> SELECT INTERVAL -'1 month - 1 second';
 ?column?
----------
 -29 days 23:59:59

改为使用以下命令之一来返回预期结果:

=> SELECT INTERVAL -'1 month 1 second';
 ?column?
----------
 -30 days 1 sec
=> SELECT INTERVAL -'30 00:00:01';
 ?column?
----------
 -30 days 1 sec

两个负号叠加会返回一个正数:

=> SELECT INTERVAL -'-1 month - 1 second';
 ?column?
----------
 29 days 23:59:59
=> SELECT INTERVAL -'-1 month 1 second';
 ?column?
----------
 30 days 1 sec

您可以使用不带空格的年-月语法。Vertica 允许输入负数月份,但与年份配对时需要两个负数。

=> SELECT INTERVAL '3-3' YEAR TO MONTH;
 ?column?
----------
 3 years 3 months
=> SELECT INTERVAL '3--3' YEAR TO MONTH;
 ?column?
----------
 2 years 9 months

当字面量类时间间隔看起来像年/月类型,但类型是天/秒(反之亦然)时,Vertica 会从左到右读取字面量类时间间隔,而数字-数字是年-月,数字 <空格> <带符号的数字> 是指定的任何单位。Vertica 将以下命令处理为 (–) 1 年 1 个月 = (–) 365 + 30 = –395 天:

=> SELECT INTERVAL '-1-1' DAY TO HOUR;
 ?column?
----------
 -395 days

如果您在字面量类时间间隔中插入空格,Vertica 会根据子类型 DAY TO HOUR 对其进行处理:(–) 1 天 – 1 小时 = (–) 24 – 1 = –23 小时:

=> SELECT INTERVAL '-1 -1' DAY TO HOUR;
 ?column?
----------
 -23 hours

两个负号叠加会返回一个正数,因此 Vertica 将以下命令处理为 (–) 1 年 – 1 个月 = (–) 365 – 30 = –335 天:

=> SELECT INTERVAL '-1--1' DAY TO HOUR;
  ?column?
----------
 -335 days

如果省略连字符后的值,则 Vertica 假定 0 个月并将以下命令处理为 1 年 0 月 –1 天 = 365 + 0 – 1 = –364 天:

=> SELECT INTERVAL '1- -1' DAY TO HOUR;
  ?column?
----------
 364 days

7 - 间隔转换

您可以使用 CAST 将字符串转换为间隔,反之亦然。

字符串到间隔

您可以如下所示将字符串转换为间隔:

CAST( [ INTERVAL[(p)] ] [-] ] interval‑literal AS INTERVAL[(p)] interval‑qualifier )

例如:

=> SELECT CAST('3700 sec' AS INTERVAL);
 ?column?
----------
 01:01:40

您可以在日期-时间或年-月子类型中投射转换间隔,但不能在其之间转换:

=> SELECT CAST(INTERVAL '4440' MINUTE as INTERVAL);
  ?column?
----------
 3 days 2 hours
=> SELECT CAST(INTERVAL -'01:15' as INTERVAL MINUTE);
 ?column?
----------
 -75 mins

间隔到字符串

您可以如下所示将间隔转换为字符串:

CAST( (SELECT interval ) AS VARCHAR[(n)] )

例如:

=> SELECT CONCAT(
  'Tomorrow at this time: ',
  CAST((SELECT INTERVAL '24 hours') + CURRENT_TIMESTAMP(0) AS VARCHAR));
                    CONCAT
-----------------------------------------------
 Tomorrow at this time: 2016-08-17 08:41:23-04
(1 row)

8 - 间隔操作

如果用间隔除以间隔,您可以获得一个 FLOAT

=> SELECT INTERVAL '28 days 3 hours' HOUR(4) / INTERVAL '27 days 3 hours' HOUR(4);
 ?column?
------------
 1.036866359447

FLOAT 除以 INTERVAL 会返回 INTERVAL

=> SELECT INTERVAL '3' MINUTE / 1.5;
 ?column?
------------
 2 mins

INTERVAL MODULO (余数)INTERVAL 返回 INTERVAL

=> SELECT INTERVAL '28 days 3 hours' HOUR % INTERVAL '27 days 3 hours' HOUR;
  ?column?
------------
 24 hours

如果添加 INTERVALTIME,则结果为 TIME,取模 24 小时:

=> SELECT INTERVAL '1' HOUR + TIME '1:30';
 ?column?
------------
 02:30:00