Categorias:

Funções de data e hora

TIME_SLICE

Calcula o início ou o fim de uma “fatia” de tempo, em que a duração da fatia é um múltiplo de uma unidade de tempo padrão (minuto, hora, dia etc.).

Esta função pode ser usada para calcular o horário de início e fim dos “buckets” de largura fixa nos quais os dados podem ser categorizados.

Consulte também:

DATE_TRUNC

Sintaxe

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

Argumentos

Obrigatório:

date_or_time_expr

A função retorna o início ou o fim da fatia que contém esta data ou hora. A expressão deve ser do tipo DATE ou TIMESTAMP_NTZ.

slice_length

Isso indica a largura da fatia (ou seja, quantas unidades de tempo estão contidas na fatia). Por exemplo, se a unidade for MONTH e a slice_length for 2, então cada fatia terá 2 meses de largura. O slice_length deve ser um número inteiro maior ou igual a 1.

date_or_time_part

Unidade de tempo do comprimento da fatia. O valor deve ser uma cadeia de caracteres contendo um dos valores listados abaixo:

  • Se a expressão de entrada for DATE: YEAR, QUARTER, MONTH, WEEK, DAY.

  • Se a expressão de entrada for TIMESTAMP_NTZ: YEAR, QUARTER, MONTH, WEEK, DAY, HOUR, MINUTE, SECOND.

Os valores não diferenciam letras maiúsculas e minúsculas.

Opcional:

start_or_end

Este é um parâmetro constante opcional que determina se o início ou o fim da fatia deve ser retornado.

Os valores suportados são ‘START’ ou ‘END’. Os valores não diferenciam letras maiúsculas e minúsculas.

O valor padrão é ‘START’.

Retornos

O tipo de dados do valor de retorno é idêntico ao tipo de dados da entrada date_or_time_expr (ou seja, TIMESTAMP_NTZ ou DATE).

Notas de uso

  • Todas as fatias estão alinhadas em relação à meia-noite de 1º de janeiro de 1970 (1970-01-01 00:00:00).

    A maioria das fatias começa em um múltiplo inteiro do comprimento da fatia em relação a 1º de janeiro de 1970. Por exemplo, se você escolher um comprimento de fatia de 15 anos, então cada fatia começará em um dos seguintes limites:

    • 1º de janeiro de 1970.

    • 1º de janeiro de 1985.

    • 1º de janeiro de 2000.

    • 1º de janeiro de 2015.

    • Etc.

    As datas anteriores a 1º de janeiro de 1970 também são válidas; por exemplo, uma fatia de 15 anos pode começar em 1º de janeiro de 1955.

    A única exceção é que, para as fatias medidas em semanas, o início das fatias está alinhado com o início da semana que contém 1º de janeiro de 1970. 1º de janeiro de 1970 era uma quinta-feira. Assim, por exemplo, se seu parâmetro de sessão WEEK_START especifica que suas semanas de calendário começam na segunda-feira, e se suas fatias são 2 semanas, então suas fatias começarão em um dos seguintes limites:

    • 29 de dezembro de 1969 (segunda-feira).

    • 12 de janeiro de 1970 (segunda-feira).

    • 25 de janeiro de 1970 (segunda-feira).

    • Etc.

    Se suas semanas de calendário começam no domingo, então suas fatias começarão no domingo:

    • 28 de dezembro de 1969 (domingo).

    • 11 de janeiro de 1970 (domingo).

    • 25 de janeiro de 1970 (domingo).

    • Etc.

    Para obter mais detalhes sobre como as semanas do calendário são tratadas, incluindo exemplos, consulte Semanas de calendário e dias úteis.

  • Embora os parâmetros para TIME_SLICE devam ser do tipo DATE ou TIMESTAMP_NTZ, você pode usar a conversão para processar valores TIMESTAMP_LTZ. Para os valores TIMESTAMP_LTZ, primeiro converta a entrada para TIMESTAMP_NTZ e depois converta de volta para TIMESTAMP_LTZ. No entanto, neste caso, as fatias que cruzam os limites do horário de verão podem ser uma hora mais longas ou uma hora mais curtas do que as fatias que não cruzam os limites do horário de verão.

  • O fim de cada fatia é o mesmo que o início da fatia seguinte. Por exemplo, se a fatia for 2 meses e o início da fatia for 2019-01-01, então o fim da fatia será 2019-03-01, não 2019-02-28. Em outras palavras, a fatia contém datas ou carimbos de data/hora maiores ou iguais ao início e menores que (mas não iguais) ao fim.

Exemplos

Encontre o início e o fim de uma fatia de 4 meses contendo uma data:

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

Encontre o início das fatias de 8 horas correspondentes a dois carimbos de data/hora:

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

Agrupar dados em “buckets” com base na data ou no carimbo de data/hora (por exemplo, agrupar dados em buckets que tenham duas semanas de gama):

Este exemplo utiliza a tabela e os dados criados abaixo:

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

Esta consulta mostra os dados em bucket:

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

Observe que a cláusula GROUP BY precisa tanto do início quanto do fim da fatia porque o compilador espera que a cláusula GROUP BY contenha todas as expressões não agregadas da cláusula de projeção.