Kategorien:

Datums- und Uhrzeitfunktionen

TIME_SLICE

Berechnet den Anfang oder das Ende eines „Zeitsegments“, wobei die Länge des Segments ein Vielfaches einer Standardzeiteinheit (Minute, Stunde, Tag usw.) ist.

Mit der Funktion können die Start- und Endzeiten von „Buckets“ fester Breite berechnet werden, in die sich Daten einteilen lassen.

Siehe auch:

DATE_TRUNC

Syntax

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

Argumente

Benötigt:

Datum_oder_Zeit_Ausdruck

Die Funktion gibt den Anfang oder das Ende des Segments zurück, das dieses Datum oder diese Uhrzeit enthält. Der Ausdruck muss den Datentyp DATE oder TIMESTAMP_NTZ aufweisen.

Segmentlänge

Dies gibt die Breite des Segments an, d. h. wie viele Zeiteinheiten im Segment enthalten sind. Wenn zum Beispiel die Einheit MONTH und die Segmentlänge 2 ist, ist jedes Segment 2 Monate lang. Die Segmentlänge muss eine ganze Zahl größer oder gleich 1 sein.

Datum_oder_Zeit_Teil:

Zeiteinheit für die Segmentlänge. Der Wert muss eine Zeichenfolge sein, die einen der folgenden Werte enthält:

  • Wenn der Eingabeausdruck ein DATEist: YEAR, QUARTER, MONTH, WEEK, DAY.

  • Wenn der Eingabeausdruck ein TIMESTAMP_NTZist: YEAR, QUARTER, MONTH, WEEK, DAY, HOUR, MINUTE, SECOND.

Bei den Werten wird nicht zwischen Groß- und Kleinschreibung unterschieden.

Optional:

Start_oder_Ende

Dies ist ein optionaler konstanter Parameter, der festlegt, ob der Anfang oder das Ende des Segments zurückgegeben werden soll.

Unterstützte Werte sind „START“ oder „END“. Bei den Werten wird nicht zwischen Groß- und Kleinschreibung unterschieden.

Der Standardwert ist START.

Rückgabewerte

Der Datentyp des Rückgabewerts ist identisch mit dem Datentyp der Eingabe Datum_oder_Zeit_Ausdruck (d. h. entweder TIMESTAMP_NTZ oder DATE).

Nutzungshinweise

  • Alle Segmente sind relativ zu Mitternacht am 1. Januar 1970 (1970-01-01 00:00:00) ausgerichtet.

    Die meisten Segmente beginnen mit einem ganzzahligen Vielfachen der Segmentlänge bezogen auf den 1. Januar 1970. Wenn Sie beispielsweise eine Segmentlänge von 15 Jahren wählen, beginnt jedes Segment an einer der folgenden Grenzen:

    • 1. Januar 1970.

    • 1. Januar 1985.

    • 1. Januar 2000.

    • 1. Januar 2015.

    • usw.

    Daten vor dem 1. Januar 1970 sind ebenfalls gültig; beispielsweise kann ein 15-Jahres-Slice am 1. Januar 1955 beginnen.

    Die einzige Ausnahme besteht darin, dass bei Segmenten, die in Wochen gemessen werden, die Anfänge der Segmente am Start der Woche ausgerichtet sind, die den 1. Januar 1970 enthält. Der 1. Januar 1970 war ein Donnerstag. Wenn Ihr Sitzungsparameter WEEK_START beispielsweise angibt, dass Ihre Kalenderwochen am Montag beginnen, und Ihre Segmente 2 Wochen breit sind, beginnen Ihre Segmente an einer der folgenden Grenzen:

    • 29. Dezember 1969 (Montag).

    • 12. Januar 1970 (Montag).

    • 25. Januar 1970 (Montag).

    • usw.

    Wenn Ihre Kalenderwochen am Sonntag beginnen, beginnen Ihre Segmente am:

    • 28. Dezember 1969 (Sonntag).

    • 11. Januar 1970 (Sonntag).

    • 25. Januar 1970 (Sonntag).

    • usw.

    Weitere Informationen zum Umgang mit Kalenderwochen, einschließlich Beispielen, finden Sie unter Kalenderwochen und Wochentage.

  • Obwohl die Parameter für TIME_SLICE vom Typ DATE oder TIMESTAMP_NTZ sein müssen, können Sie mit Umwandlungen auch TIMESTAMP_LTZ-Werte verarbeiten. Wandeln Sie TIMESTAMP_LTZ-Werte zunächst in TIMESTAMP_NTZ um und dann zurück in TIMESTAMP_LTZ. In diesem Fall können mit Segmente, die die Sommerzeitgrenzen überschreiten, entweder eine Stunde länger oder eine Stunde kürzer sein als Segmente, die keine Sommerzeitgrenzen überschreiten.

  • Das Ende eines Segments ist stets identisch mit dem Anfang des folgenden Segments. Wenn das Segment beispielsweise 2 Monate breit ist und der Beginn des Segments 2019-01-01 ist, dann lautet das Ende des Segments 2019-03-01 und nicht 2019-02-28. Mit anderen Worten: Das Segment enthält Datumsangaben oder Zeitstempel, die größer oder gleich dem Anfang und kleiner als das (aber nicht gleich dem) Ende sind.

Beispiele

Suchen Sie den Anfang und das Ende eines 4-Monats-Segments, das ein Datum enthält:

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

Suchen Sie den Anfang von 8-Stunden-Segmenten, die zwei Zeitstempeln entsprechen:

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

Gruppieren Sie Daten anhand des Datums oder Zeitstempels in „Buckets“ (z. B. gruppieren Sie Daten in Buckets, die zwei Wochen breit sind):

In diesem Beispiel werden die im Folgenden erstellten Tabellen und Daten verwendet:

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

Diese Abfrage zeigt die in Buckets gruppierten Daten an:

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

Beachten Sie, dass die GROUP BY-Klausel sowohl den Anfang des Segments als auch das Ende des Segments erfordert, da der Compiler erwartet, dass die GROUP BY-Klausel alle nicht aggregierten Ausdrücke der Projektionsklausel enthält.