日期、时间戳和间隔运算符 - Amazon Kinesis Data Analytics

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

日期、时间戳和间隔运算符

算术运算符 +、-、*、/、

操作符 描述 注意

+

间隔 + 间隔 = 间隔

间隔 + 日期时间 = 日期时间

日期时间 + 间隔 = 日期时间

-

间隔-间隔 = 间隔

日期时间-间隔 = 日期时间

( <datetime> - <datetime> ) 日期、时间戳和间隔运算符 <interval qualifier> = 时间间隔

*

间隔 * 数字 = 间隔

数字 * 间隔 = 间隔

/

间隔/数字 = 间隔

示例

示例 运算 结果

1

间隔 '1' 天 + 间隔 '3' 天

间隔 '4' 天

2

间隔 '1' 天 + 间隔 '3 4' 天到小时

间隔 '+4 04' 从一天到一小时

3

间隔 '1' 天-间隔 '3 4' 天到小时

间隔 '-2 04' 从一天到一小时

4

间隔 '1' 年 + 间隔 '3-4' 年对月

间隔 '+4-04' 年与月

5

2 * 间隔 '3 4' 从一天到一小时

间隔 '6 8' 天到小时

6

间隔 '3 4' 从一天到一小时/ 2

间隔 '1 14' 从一天到一小时

在示例 3 中,'3 4 DAY 表示 3 天 4 小时,因此该行的结果表示 24 小时减去 76 小时,减去 52 小时,即负 2 天零 4 小时。

示例 4 使用 TO MONTH 而不是 TO HOUR,因此指定为 “3-4” 的时间间隔表示 3 年零 4 个月,或 40 个月。

在示例 6 中,“/2” 适用于间隔 '3 4',即 76 小时,其中一半为 38,或 1 天零 14 小时。

间隔运算的更多示例

Streaming SQL 还支持减去两个日期时间,给出一个间隔。您可以指定想要的结果间隔类型,如下所示:

(<datetime> - <datetime>) <interval qualifier>

以下示例显示了在 Amazon Kinesis Data Analytics 应用程序中可能有用的操作。

例 1 — 时差(以分钟到最接近的秒或以秒为单位)
values cast ((time  '12:03:34' - time '11:57:23') minute to second as varchar(8)); +---------+ EXPR$0   +---------+ +6:11   +---------+ 1 row selected ............... 6 minutes, 11 seconds or values cast ((time  '12:03:34' - time '11:57:23') second as varchar(8)); +---------+ EXPR$0   +---------+ +371     +---------+ 1 row selected
例 2 — 时差(仅以分钟为单位)
values cast ((time  '12:03:34' - time '11:57:23') minute as varchar(8)); +---------+ EXPR$0   +---------+ +6       +---------+ 1 row selected ............... 6 minutes; seconds ignored. values cast ((time  '12:03:23' - time '11:57:23') minute as varchar(8)); +---------+ EXPR$0   +---------+ +6       +---------+ 1 row selected ............... 6 minutes
例 3 — 时间与时间戳的差异(以天到最接近的秒为单位)无效
values cast ((time '12:03:34'-timestamp '2004-04-29 11:57:23') day to second as varchar(8)); Error: From line 1, column 14 to line 1, column 79: Parameters must be of the same type
例 4 — 时间戳差(以天到最接近的秒为单位)
values cast ((timestamp  '2004-05-01 12:03:34' - timestamp '2004-04-29 11:57:23') day to                second as varchar(8)); +-----------+  EXPR$0   +-----------+ +2 00:06   +-----------+ 1 row selected ............... 2 days, 6 minutes ............... Although "second" was specified above, the varchar(8) happens to allow only room enough to show only the minutes, not the seconds. The example below expands to varchar(11), showing the full result: values cast ((timestamp  '2004-05-01 12:03:34' - timestamp '2004-04-29 11:57:23') day to                second as varchar(11)); +--------------+    EXPR$0     +--------------+ +2 00:06:11   +--------------+ 1 row selected ............... 2 days, 6 minutes, 11 seconds
例 5 — 时间戳差(以天到最接近的秒为单位)
values cast ((timestamp  '2004-05-01 1:03:34' - timestamp '2004-04-29 11:57:23') day to                second as varchar(11)); +--------------+    EXPR$0     +--------------+ +1 13:06:11   +--------------+ 1 row selected ............... 1 day, 13 hours, 6 minutes, 11 seconds values cast ((timestamp  '2004-05-01 13:03:34' - timestamp '2004-04-29 11:57:23') day to                second as varchar(11)); +--------------+    EXPR$0     +--------------+ +2 01:06:11   +--------------+ 1 row selected ............... 2 days, 1 hour, 6 minutes, 11 seconds
例 6 — 时间戳差(以天为单位)
values cast ((timestamp  '2004-05-01 12:03:34' - timestamp '2004-04-29 11:57:23') day                as varchar(8)); +---------+ EXPR$0   +---------+ +2       +---------+ 1 row selected ............... 2 days
例 7 — 时差(以天为单位)
values cast ((date '2004-12-02 ' - date '2003-12-01 ') day  as varchar(8)); Error: Illegal DATE literal '2004-12-02 ': not in format 'yyyy-MM-dd' .............. Both date literals end with a space;  disallowed. values cast ((date '2004-12-02' - date '2003-12-01 ') day  as varchar(8)); Error: Illegal DATE literal '2003-12-01 ': not in format 'yyyy-MM-dd' .............. Second date literal still ends with a space;  disallowed. values cast ((date '2004-12-02' - date '2003-12-01') day  as varchar(8)); +---------+ EXPR$0   +---------+ +367     +---------+ 1 row selected ............... 367 days
例 8 — 不支持(简单的日期差异)

如果您不指定 “天” 作为预期单位,如下所示,则不支持减法。

    values cast ((date '2004-12-02' - date '2003-12-01') as varchar(8));     Error: From line 1, column 15 to line 1, column 51:            Cannot apply '-' to arguments of type '<DATE> - <DATE>'.     Supported form(s): '<NUMERIC> - <NUMERIC>'                        '<DATETIME_INTERVAL> - <DATETIME_INTERVAL>'                        '<DATETIME> - <DATETIME_INTERVAL>'

为什么在转换示例中使用 “as varchar”?

<expression>在上面的示例中使用 “值转换 (AS varchar (N))” 语法的原因是,虽然上面使用的 SQLLine 客户端(运行 Amazon Kinesis Data Analytics))确实会返回间隔,但 JDBC 不支持返回该结果以显示间隔。因此,使用 “值” 语法来查看/显示它。

如果你关闭Amazon Data Analytics(用! kill command)或者如果你在运行 SQLLine 之前没有启动它,那么你可以从 Amazon Kinesis Data Analytics 主页的 bin 子目录中运行 sqllineEngine(而不是 SQLLineClient),它可以在没有 Amazon Kinesis Data Analytics 应用程序或 JDBC 的情况下显示你的结果:

指定间隔的规则

日间隔文字是表示单个间隔值的字符串:例如 '10' 秒。请注意,它分为两部分:值(必须始终使用单引号)和限定符(此处为 SECONDS),后者给出值的单位。

预选头采用以下形式:

DAY  HOUR  MINUTE  SECOND [TO HOUR  MINUTE  SECOND]
注意

年到月间隔需要用短划线分隔值,而日到小时间隔使用空格分隔值,如该主题的第 2、3、5 和 6 个示例所示。

此外,前导项必须比可选的尾随项具有更大的意义,因此这意味着您只能指定:

 DAY  HOUR  MINUTE  SECOND  DAY TO HOUR  DAY TO MINUTE  DAY TO SECOND  HOUR TO MINUTE  HOUR TO SECOND  MINUTE TO SECOND

理解这些的最简单方法可能是将 X 转换为 “X 到最接近的 Y”。因此,DAY TO HOR 是 “天到最接近的小时”。

当天、小时或分钟是前导项时,可以指定精度,例如,天 (3) 到 HOUR,表示值中关联字段可以包含的位数。最大精度为 10,默认精度为 2。您无法在后缀项中为小时或分钟指定精度,它们的精度始终为 2。因此,例如,小时 (3) 到分钟是合法的,而小时到分钟 (3) 不是。

SECOND 也可以采用精度,但其指定方式因它是前导字段还是后导字段而异。

  • 如果 SECOND 是前导字段,则可以指定小数点前后的数字。例如,SECOND (3,3) 将允许您指定最多 999.999 秒。默认值是 (2,3),这实际上与 SQL: 2008 规范有所偏差(应该是 (2,6),但我们只有毫秒精度)。

  • 如果 SECOND 是尾随字段,则只能指定小数秒的精度,即下面显示的秒的小数点之后的部分。例如,SECOND (3) 将表示毫秒。默认值为小数点后 3 位数,但如上所述,这与标准 6 有所偏差。

至于值,它一般采用以下形式:

 [+-]'[+-]DD HH:MM:SS.SSS'

其中 DD 是表示天数的数字,HH 小时、MM 分钟,SS.SSS 是秒(如果明确指定了精度,请适当调整位数)。

并非所有值都必须包含所有字段,您可以从正面或背面修剪,但不能从中间修剪。所以你可以把它设为 “DD HH” 或 “MM: SS.SSS”,但不能改为 “DD MM”。

但是,无论你怎么写,该值都必须与限定符匹配,如下所示:

INTERVAL '25 3' DAY to HOUR ------> legal INTERVAL '3:45:04.0' DAY TO HOUR --> illegal

正如 SQL 规范中所述,如果未明确指定精度,则暗示精度为 2。因此:

  • 间隔 '120' 分钟是非法间隔。所需间隔的合法形式是间隔 '120' 分钟 (2)

    and

  • 间隔 '120' 秒不合法。所需间隔的合法形式是间隔 '120' 秒 (3)。

      values INTERVAL '120' MINUTE(2);   Error: From line 1, column 8 to line 1, column 31:                       Interval field value 120 exceeds precision of MINUTE(2) field   values INTERVAL '120' MINUTE(3);   Conversion not supported

此外,如果小时、分钟或秒不是前导字段,则它们必须处于以下范围内(取自 SQL: 2008 基础规范主题 4.6.3 的表 6),如下所示:

 HOUR: 0-23  MINUTE: 0-59  SECOND: 0-59.999

年月间隔相似,唯一的不同是限定符如下所示:

 YEAR  MONTH  YEAR TO MONTH

可以像 DAY 和 HOUR 一样指定精度,最大值 10 和默认值 2 相同。

年月的值格式为:'YY-MM'。如果 MONTH 是尾随字段,则它必须在 0-11 的范围内。

<interval qualifier> := <start field> TO <end field>  <single datetime field> <start field> := <non-second primary datetime field> [ <left paren> <interval leading field precision> <right paren> ] <end field> := <non-second primary datetime field>  SECOND [ <left paren> <interval fractional seconds precision> <right paren> ] <single datetime field> := <non-second primary datetime field> [ <left paren> <interval leading field precision> <right paren> ]   SECOND [ <left paren> <interval leading field precision>           [ <comma> <interval fractional seconds precision> ] <right paren> ] <primary datetime field> := <non-second primary datetime field>       SECOND <non-second primary datetime field> := YEAR  MONTH  DAY  HOUR      MINUTE <interval fractional seconds precision> := <unsigned integer> <interval leading field precision> := <unsigned integer>