Catégories :

Fonctions de date et d’heure

TIME_SLICE

Calcule le début ou la fin d’une « tranche » de temps, où la longueur de la tranche est un multiple d’une unité de temps standard (minute, heure, jour, etc.).

Cette fonction peut être utilisée pour calculer les heures de début et de fin des « compartiments » à largeur fixe dans lesquels les données peuvent être classées.

Voir aussi :

DATE_TRUNC

Syntaxe

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

Arguments

Obligatoire :

expr_date_ou_heure

La fonction renvoie le début ou la fin de la tranche contenant cette date ou cette heure. L’expression doit avoir un type DATE ou TIMESTAMP_NTZ.

longueur_tranche

Cela indique la largeur de la tranche, c’est-à-dire combien d’unités de temps sont contenues dans la tranche. Par exemple, si l’unité est MONTH et que longueur_tranche est égale à 2, chaque tranche a une largeur de 2 mois. La longueur_tranche doit être un entier supérieur ou égal à 1.

partie_date_ou_heure

Unité de temps pour la longueur de la tranche. La valeur doit être une chaîne contenant l’une des valeurs répertoriées ci-dessous :

  • Si l’expression d’entrée est un DATE : YEAR, QUARTER, MONTH, WEEK, DAY.

  • Si l’expression d’entrée est un TIMESTAMP_NTZ : YEAR, QUARTER, MONTH, WEEK, DAY, HOUR, MINUTE, SECOND.

Les valeurs ne sont pas sensibles à la casse.

Facultatif :

début_ou_fin

Ce paramètre de constante facultatif détermine si le début ou la fin de la tranche doit être renvoyé.

Les valeurs prises en charge sont “START” ou “END”. Les valeurs ne sont pas sensibles à la casse.

La valeur par défaut est START.

Renvoie

Le type de données de la valeur renvoyée est identique à celui de l’entrée expr_date_ou_heure (c’est-à-dire TIMESTAMP_NTZ ou DATE).

Notes sur l’utilisation

  • Toutes les tranches sont alignées par rapport au 1er janvier 1970 à minuit (1970-01-01 00:00:00).

    La plupart des tranches commencent par un multiple entier de la longueur de la tranche par rapport au 1er janvier 1970. Par exemple, si vous choisissez une longueur de tranche de 15 ans, chaque tranche commencera sur l’une des limites suivantes :

    • 1er janvier 1970.

    • 1er janvier 1985.

    • 1er janvier 2000.

    • 1er janvier 2015.

    • Etc.

    Les dates antérieures au 1er janvier 1970 sont également valables ; par exemple, une tranche de 15 ans peut commencer le 1er janvier 1955.

    La seule exception est que, pour les tranches mesurées en semaines, les débuts des tranches sont alignés sur le début de la semaine contenant le 1er janvier 1970. Le 1er janvier 1970 était un jeudi. Ainsi, par exemple, si votre paramètre de session WEEK_START indique que vos semaines calendaires commencent le lundi, et si vos tranches sont de 2 semaines, vos tranches commenceront sur l’une des limites suivantes :

    • 29 décembre 1969 (lundi).

    • 12 janvier 1970 (lundi).

    • 25 janvier 1970 (lundi).

    • Etc.

    Si vos semaines calendaires commencent le dimanche, vos tranches commenceront le :

    • 28 décembre 1969 (dimanche).

    • 11 janvier 1970 (dimanche).

    • 25 janvier 1970 (dimanche).

    • Etc.

    Pour plus de détails sur la gestion des semaines du calendrier, y compris des exemples, voir Semaines civiles et jours de semaine.

  • Bien que les paramètres dans TIME_SLICE doivent être de type DATE ou TIMESTAMP_NTZ, vous pouvez utiliser la conversion pour traiter les valeurs TIMESTAMP_LTZ. Pour les valeurs TIMESTAMP_LTZ, convertissez d’abord l’entrée en TIMESTAMP_NTZ, puis reconvertissez-la en TIMESTAMP_LTZ. Toutefois, dans ce cas, les tranches dépassant l’heure d’été peuvent être plus longues d’une heure ou plus courtes que les tranches ne franchissant pas les limites d’heure d’été.

  • La fin de chaque tranche est la même que le début de la tranche suivante. Par exemple, si la tranche est de 2 mois et que le début de la tranche est le 2019-01-01, la fin de la tranche sera le 2019-03-01 et non le 2019-02-28. En d’autres termes, la tranche contient des dates ou des horodatages supérieurs ou égaux au début et inférieurs (mais non égaux) à la fin.

Exemples

Recherchez le début et la fin d’une tranche de 4 mois contenant une date :

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   |
+------------+----------------+--------------+

Recherchez le début des tranches de 8 heures correspondant à deux horodatages :

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 |
+-------------------------+-------------------------+-------------------------+-------------------------+

Regroupez les données dans des « compartiments » en fonction de la date ou de l’horodatage (par exemple, regroupez les données dans des compartiments de deux semaines) :

Cet exemple utilise la table et les données créées ci-dessous :

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);

Cette requête affiche les données compartimentées :

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 |
+----------------+--------------+----------------------+-------------------+

Notez que la clause GROUP BY a besoin du début et de la fin de la tranche, car le compilateur s’attend à ce que la clause GROUP BY contienne toutes les expressions non agrégées de la clause de projection.