类别:

日期和时间函数

TIME_SLICE

计算时间“切片”的开始或结束,其中切片的长度是标准时间单位(分钟、小时、天等)的倍数。

此函数可用于计算可以对数据进行分类的固定宽度“桶”的开始和结束时间。

另请参阅:

DATE_TRUNC

语法

TIME_SLICE( <date_or_time_expr> , <slice_length> , <date_or_time_part> [ , <start_or_end> ] )
Copy

实参

必填:

date_or_time_expr

该函数返回包含此日期或时间的切片的开始或结束。表达式的类型必须为 DATE 或 TIMESTAMP_NTZ。

slice_length

这表示切片的宽度(即切片中包含多少个时间单位)。例如,如果单位为 MONTH,且 slice_length 为 2,则每个切片的宽度为 2 个月。slice_length 必须是大于或等于 1 的整型。

date_or_time_part

切片长度的时间单位。该值必须是包含下列其中一个值的字符串:

  • 如果输入表达式是 DATE:YEAR、QUARTER、MONTH、WEEK、DAY。

  • 如果输入表达式是 TIMESTAMP_NTZ:YEAR、QUARTER、MONTH、WEEK、DAY、HOUR、MINUTE、SECOND。

这些值不区分大小写。

可选:

start_or_end

这是一个可选的常量参数,用于确定应返回切片的起点或终点。

支持的值为“START”或“END”。这些值不区分大小写。

默认值为“START”。

返回

返回值的数据类型与输入 date_or_time_expr 的数据类型相同(即 TIMESTAMP_NTZ 或 DATE)。

使用说明

  • 所有切片都相对于 1970 年 1 月 1 日午夜 (1970-01-01 00:00:00) 对齐。

    大多数切片从相对于 1970 年 1 月 1 日的切片长度的整型倍数开始。例如,如果选择切片长度为 15 年,则每个切片将从以下其中一个边界开始:

    • 1970 年 1 月

    • 1985 年 1 月

    • 2000 年 1 月

    • 2015 年 1 月

    1970 年 1 月 1 日之前的日期也有效;例如,15 年切片可以从 1955 年 1 月 1 日开始。

    唯一的例外是,对于以周为单位的切片,切片的开始时间与包含 1970 年 1 月 1 日的 开始时间对齐。1970 年 1 月 1 日是星期四。因此,例如,如果 WEEK_START 会话参数指定日历周从星期一开始,并且切片是 2 周,那么切片将从以下其中一个边界开始:

    • 1969 年 12 月 29 日(星期一)。

    • 1970 年 1 月 12 日(星期一)。

    • 1970 年 1 月 25 日(星期一)。

    如果您的日历周从星期日开始,则切片将从以下日期开始:

    • 1969 年 12 月 28 日(星期日)。

    • 1970 年 1 月 11 日(星期日)。

    • 1970 年 1 月 25 日(星期日)。

    有关如何处理日历周的更多详细信息(包括示例),请参阅 日历周和工作日

  • 尽管 TIME_SLICE 的参数类型必须是 DATE 或 TIMESTAMP_NTZ,但可以使用类型转换来处理 TIMESTAMP_LTZ 值。对于 TIMESTAMP_LTZ 值,先将输入类型转换为 TIMESTAMP_NTZ,然后再类型转换回 TIMESTAMP_LTZ。但是,在这种情况下,跨越夏令时边界的切片可以比不跨越夏令时边界的切片长一小时或短一小时。

  • 每个切片的结尾与下一个切片的开头相同。例如,如果切片是 2 个月,切片的开始时间为 2019-01-01,则切片的结束时间为 2019-03-01,而不是 2019-02-28。换句话说,切片包含大于或等于开始日期或时间戳,但小于(但不等于)结束日期或时间戳的日期或时间戳。

示例

查找包含日期的 4 个月切片的开始和结束:

SELECT '2019-02-28'::DATE AS "DATE",
       TIME_SLICE("DATE", 4, 'MONTH', 'START') AS "START OF SLICE",
       TIME_SLICE("DATE", 4, 'MONTH', 'END') AS "END OF SLICE";
+------------+----------------+--------------+
| DATE       | START OF SLICE | END OF SLICE |
|------------+----------------+--------------|
| 2019-02-28 | 2019-01-01     | 2019-05-01   |
+------------+----------------+--------------+
Copy

查找对应于两个时间戳的 8 小时切片的开始:

SELECT '2019-02-28T01:23:45.678'::TIMESTAMP_NTZ AS "TIMESTAMP 1",
       '2019-02-28T12:34:56.789'::TIMESTAMP_NTZ AS "TIMESTAMP 2",
       TIME_SLICE("TIMESTAMP 1", 8, 'HOUR') AS "SLICE FOR TIMESTAMP 1",
       TIME_SLICE("TIMESTAMP 2", 8, 'HOUR') AS "SLICE FOR TIMESTAMP 2";
+-------------------------+-------------------------+-------------------------+-------------------------+
| TIMESTAMP 1             | TIMESTAMP 2             | SLICE FOR TIMESTAMP 1   | SLICE FOR TIMESTAMP 2   |
|-------------------------+-------------------------+-------------------------+-------------------------|
| 2019-02-28 01:23:45.678 | 2019-02-28 12:34:56.789 | 2019-02-28 00:00:00.000 | 2019-02-28 08:00:00.000 |
+-------------------------+-------------------------+-------------------------+-------------------------+
Copy

根据日期或时间戳将数据分组到“桶”中(例如,将数据分组到两周宽的桶中):

此示例使用下面创建的表和数据:

CREATE TABLE accounts (ID INT, billing_date DATE, balance_due NUMBER(11, 2));

INSERT INTO accounts (ID, billing_date, balance_due) VALUES
    (1, '2018-07-31', 100.00),
    (2, '2018-08-01', 200.00),
    (3, '2018-08-25', 400.00);
Copy

此查询显示已分组到桶中的数据:

SELECT
       TIME_SLICE(billing_date, 2, 'WEEK', 'START') AS "START OF SLICE",
       TIME_SLICE(billing_date, 2, 'WEEK', 'END')   AS "END OF SLICE",
       COUNT(*) AS "NUMBER OF LATE BILLS",
       SUM(balance_due) AS "SUM OF MONEY OWED"
    FROM accounts
    WHERE balance_due > 0    -- bill hasn't yet been paid
    GROUP BY "START OF SLICE", "END OF SLICE";
+----------------+--------------+----------------------+-------------------+
| START OF SLICE | END OF SLICE | NUMBER OF LATE BILLS | SUM OF MONEY OWED |
|----------------+--------------+----------------------+-------------------|
| 2018-07-23     | 2018-08-06   |                    2 |            300.00 |
| 2018-08-20     | 2018-09-03   |                    1 |            400.00 |
+----------------+--------------+----------------------+-------------------+
Copy

请注意,GROUP BY 子句需要切片的开头和切片的结尾,因为编译器希望该 GROUP BY 子句包含投影子句的所有非聚合表达式。

语言: 中文