Kategorien:

Funktionen für semistrukturierte und strukturierte Daten (höhere Ordnung)

REDUCE

Reduziert ein Array auf der Grundlage der Logik eines Lambda-Ausdrucks auf einen einzigen Wert.

Die Funktion REDUCE benötigt ein Array, einen anfänglichen Akkumulatorwert und eine Lambda-Funktion. Sie wendet die Lambda-Funktion auf jedes Element des Arrays an und aktualisiert den Akkumulator mit jedem Ergebnis. Nachdem alle Elemente verarbeitet wurden, gibt REDUCE den endgültigen Akkumulatorwert zurück.

Siehe auch:

Verwenden Sie Lambda-Funktionen auf Daten mit Snowflake Funktionen höherer Ordnung

Syntax

REDUCE( <array> , <init> [ <datatype> ] , <lambda_expression> )
Copy

Argumente

array

Das Array, das die zu reduzierenden Elemente enthält Das Feld kann semistrukturiert oder strukturiert sein.

init [ datatype ]

Der anfängliche Akkumulatorwert.

lambda_expression

Ein Lambda-Ausdruck, der die Reduktionslogik für jedes Array-Element definiert.

Der Lambda-Ausdruck muss in der folgenden Syntax angegeben werden:

<acc> [ <datatype> ] , <value> [ <datatype> ] -> <expr>
Copy

Das Argument acc ist der Akkumulator und das Argument value ist das aktuelle Element, das im Array verarbeitet wird.

Rückgabewerte

Diese Funktion kann einen Wert eines beliebigen Datentyps zurückgeben.

Wenn das Eingabearray leer ist, dann gibt die Funktion den Anfangswert des Akkumulators zurück.

Die Funktion gibt in diesen Fällen NULL zurück:

  • Das Eingabearray ist NULL.

  • Der Anfangswert des Akkumulators ist NULL.

  • Die Lambda-Funktion gibt NULL zurück.

Nutzungshinweise

  • Wenn der Datentyp für ein Lambda-value-Argument explizit angegeben ist, wird das Array-Element vor dem Lambda-Aufruf in den angegebenen Typ implizit umgewandelt (Koersion). Weitere Informationen zur Koersion finden Sie unter Datentypkonvertierung.

  • Die Typüberprüfung erzwingt, dass der Anfangswert des Akkumulators, das Lambda-Argument des Akkumulators und der Rückgabewert der Lambda-Ausführung alle denselben logischen und physischen Typ haben. Wenn Umwandeln verwendet wird, um diese Anforderung zu erfüllen, wird der größte physische Typ von den dreien verwendet.

  • Das Argument value kann Zwischenwerte haben NULL. Ein Beispiel dazu finden Sie unter NULL-Werte in einem Array überspringen.

Beispiele

Die folgenden Beispiele verwenden die Funktion REDUCE.

Summe der Werte in einem Array berechnen

Verwenden Sie die Funktion REDUCE, um die Summe der Werte in einem Array zurückzugeben und geben Sie 0 für den anfänglichen Akkumulatorwert an:

SELECT REDUCE([1,2,3],
              0,
              (acc, val) -> acc + val)
  AS sum_of_values;
Copy
+---------------+
| SUM_OF_VALUES |
|---------------|
|             6 |
+---------------+

Dieses Beispiel ist dasselbe wie das vorherige, aber es gibt ein strukturiertes Array vom Typ INT an:

SELECT REDUCE([1,2,3]::ARRAY(INT),
              0,
              (acc, val) -> acc + val)
  AS sum_of_values_structured;
Copy
+--------------------------+
| SUM_OF_VALUES_STRUCTURED |
|--------------------------|
|                        6 |
+--------------------------+

Verwenden Sie die Funktion REDUCE, um die Summe der Werte in einem Array zurückzugeben und geben Sie 10 für den anfänglichen Akkumulatorwert an:

SELECT REDUCE([1,2,3],
              10,
              (acc, val) -> acc + val)
  AS sum_of_values_plus_10;
Copy
+-----------------------+
| SUM_OF_VALUES_PLUS_10 |
|-----------------------|
|                    16 |
+-----------------------+

Berechnen Sie die Summe der Quadrate jedes Wertes in einem Array

Verwenden Sie die Funktion REDUCE, um die Summe des Quadrats jedes Wertes im Array zurückzugeben, und geben Sie 0 für den anfänglichen Akkumulatorwert an:

SELECT REDUCE([1,2,3],
              0,
              (acc, val) -> acc + val * val)
  AS sum_of_squares;
Copy
+----------------+
| SUM_OF_SQUARES |
|----------------|
|             14 |
+----------------+

NULL-Werte in einem Array überspringen

In diesem Beispiel enthält das Argument array die NULL-Werte. Wenn dieses Array an die Funktion REDUCE übergeben wird, enthält der Akkumulator NULL-Zwischenwerte.

Verwenden Sie die REDUCE-Funktion, um die Summe der Werte im Array zurückzugeben, und verwenden Sie die IFNULL-Funktion in der Logik des Lambda-Ausdrucks, um NULL-Werte im Array zu überspringen. Der Lambda-Ausdruck verwendet die Funktion IFNULL, um jeden Wert im Array nach der folgenden Logik zu verarbeiten:

  • Wenn acc + val NULL ist, dann wird es acc + 0.

  • Wenn acc + val nicht NULL ist, dann wird es acc + val.

Führen Sie die Abfrage aus:

SELECT REDUCE([1,NULL,2,NULL,3,4],
              0,
              (acc, val) -> IFNULL(acc + val, acc + 0))
  AS SUM_OF_VALUES_SKIP_NULL;
Copy
+-------------------------+
| SUM_OF_VALUES_SKIP_NULL |
|-------------------------|
|                      10 |
+-------------------------+

Zeichenfolgen generieren

Verwenden Sie die Funktion REDUCE, um eine Liste von Zeichenfolgen zurückzugeben, indem Sie jeden Wert im Array aneinanderreihen:

SELECT REDUCE(['a', 'b', 'c'],
              '',
              (acc, val) -> acc || ' ' || val)
  AS string_values;
Copy
+---------------+
| STRING_VALUES |
|---------------|
|  a b c        |
+---------------+

Ein Array für den Akkumulator verwenden

Verwenden Sie die REDUCE-Funktion zusammen mit der ARRAY_PREPEND-Funktion in der Logik des Lambda-Ausdrucks,, um ein Array zurückzugeben, das die Reihenfolge des Eingabearrays umkehrt:

SELECT REDUCE([1, 2, 3, 4],
              [],
              (acc, val) -> ARRAY_PREPEND(acc, val))
  AS reverse_order;
Copy
+---------------+
| REVERSE_ORDER |
|---------------|
| [             |
|   4,          |
|   3,          |
|   2,          |
|   1           |
| ]             |
+---------------+

Bedingte Logik verwenden

Verwenden Sie die REDUCE-Funktion zusammen mit der IFF-Funktion in der Logik des Lambda-Ausdrucks, um eine Aktion auf der Grundlage einer bedingten Logik auszuführen, ähnlich wie bei einem if-then-Ausdruck. Dieses Beispiel verwendet die folgende Logik im Lambda-Ausdruck:

  • Wenn der Wert des Arrays kleiner als sieben ist, dann quadrieren Sie ihn und addieren ihn zum Akkumulator.

  • Wenn der Wert des Arrays größer oder gleich sieben ist, dann addieren Sie ihn zum Akkumulator, ohne ihn zu quadrieren.

SELECT REDUCE([5,10,15],
              0,
              (acc, val) -> IFF(val < 7, acc + val * val, acc + val))
  AS conditional_logic;
Copy
+-------------------+
| CONDITIONAL_LOGIC |
|-------------------|
|                50 |
+-------------------+

Reduziert ein Array von Elementen in einer Tabelle auf einen einzigen Wert.

Angenommen, Sie haben eine Tabelle namens orders mit den Spalten order_id, order_date und order_detail. Die Spalte order_detail ist ein Array mit den Einzelposten, deren Einkaufsmenge und der Zwischensumme. Die Tabelle enthält zwei Zeilen mit Daten. Die folgende SQL-Anweisung erstellt diese Tabelle und fügt die Zeilen ein:

CREATE OR REPLACE TABLE orders AS
  SELECT 1 AS order_id, '2024-01-01' AS order_date, [
    {'item':'UHD Monitor', 'quantity':3, 'subtotal':1500},
    {'item':'Business Printer', 'quantity':1, 'subtotal':1200}
  ] AS order_detail
  UNION SELECT 2 AS order_id, '2024-01-02' AS order_date, [
    {'item':'Laptop', 'quantity':5, 'subtotal':7500},
    {'item':'Noise-canceling Headphones', 'quantity':5, 'subtotal':1000}
  ] AS order_detail;

SELECT * FROM orders;
Copy
+----------+------------+-------------------------------------------+
| ORDER_ID | ORDER_DATE | ORDER_DETAIL                              |
|----------+------------+-------------------------------------------|
|        1 | 2024-01-01 | [                                         |
|          |            |   {                                       |
|          |            |     "item": "UHD Monitor",                |
|          |            |     "quantity": 3,                        |
|          |            |     "subtotal": 1500                      |
|          |            |   },                                      |
|          |            |   {                                       |
|          |            |     "item": "Business Printer",           |
|          |            |     "quantity": 1,                        |
|          |            |     "subtotal": 1200                      |
|          |            |   }                                       |
|          |            | ]                                         |
|        2 | 2024-01-02 | [                                         |
|          |            |   {                                       |
|          |            |     "item": "Laptop",                     |
|          |            |     "quantity": 5,                        |
|          |            |     "subtotal": 7500                      |
|          |            |   },                                      |
|          |            |   {                                       |
|          |            |     "item": "Noise-canceling Headphones", |
|          |            |     "quantity": 5,                        |
|          |            |     "subtotal": 1000                      |
|          |            |   }                                       |
|          |            | ]                                         |
+----------+------------+-------------------------------------------+

Verwenden Sie die Funktion REDUCE, um die Zwischensumme für alle Artikel in jeder Bestellung zu erhalten:

SELECT order_id,
       order_date,
       REDUCE(o.order_detail,
              0,
              (acc, val) -> acc + val:subtotal) subtotal_sum
  FROM orders o;
Copy
+----------+------------+--------------+
| ORDER_ID | ORDER_DATE | SUBTOTAL_SUM |
|----------+------------+--------------|
|        1 | 2024-01-01 |         2700 |
|        2 | 2024-01-02 |         8500 |
+----------+------------+--------------+

Verwenden Sie die Funktion REDUCE, um eine Auflistung der verkauften Artikel in jeder Bestellung zu erhalten:

SELECT order_id,
       order_date,
       REDUCE(o.order_detail,
              '',
              (acc, val) -> val:item || '\n' || acc) items_sold
  FROM orders o;
Copy
+----------+------------+-----------------------------+
| ORDER_ID | ORDER_DATE | ITEMS_SOLD                  |
|----------+------------+-----------------------------|
|        1 | 2024-01-01 | Business Printer            |
|          |            | UHD Monitor                 |
|          |            |                             |
|        2 | 2024-01-02 | Noise-canceling Headphones  |
|          |            | Laptop                      |
|          |            |                             |
+----------+------------+-----------------------------+