Catégories :

Fonctions de données semi-structurées et structurées (Ordre supérieur)

REDUCE

Réduit un tableau à une valeur unique basée sur la logique d’une expression lambda.

La fonction REDUCE prend un tableau, une valeur d’accumulateur initiale et une fonction lambda. Il applique la fonction lambda à chaque élément du tableau, mettant à jour l’accumulateur avec chaque résultat. Après avoir traité tous les éléments, REDUCE renvoie la valeur finale de l’accumulateur.

Voir aussi :

Utilisation de fonctions Lambda sur les données avec les fonctions d’ordre supérieur de Snowflake

Syntaxe

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

Arguments

array

Tableau contenant les éléments à transformer. Le tableau peut être semi-structuré ou structuré.

init [ datatype ]

Valeur initiale de l’accumulateur.

lambda_expression

Expression lambda qui définit la logique de réduction sur chaque élément du tableau.

L’expression lambda doit être spécifiée dans la syntaxe suivante :

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

L’argument acc est l’accumulateur et l’argument value est l’élément en cours de traitement dans le tableau.

Renvoie

Cette fonction peut renvoyer une valeur de n’importe quel type de données.

Si le tableau d’entrée est vide, la fonction renvoie la valeur initiale de l’accumulateur.

La fonction renvoie NULL dans les cas suivants :

  • Le tableau d’entrée est NULL.

  • La valeur initiale de l’accumulateur est NULL.

  • La fonction lambda renvoie NULL.

Notes sur l’utilisation

  • Lorsque le type de données de l’argument value lambda est explicitement spécifié, l’élément du tableau est contraint de se convertir dans le type spécifié avant l’invocation de lambda. Pour des informations sur la coercition ou contrainte de conversion, voir Conversion de type de données.

  • La vérification de type garantit que la valeur initiale de l’accumulateur, l’argument lambda de l’accumulateur et la valeur de retour de l’exécution lambda ont tous les mêmes types logiques et physiques. Si casting est utilisé pour répondre à cette exigence, le plus grand type physique des trois est utilisé.

  • L’argument value peut avoir des valeurs NULL intermédiaires. Pour un exemple, voir Ignorer les valeurs NULL dans un tableau.

Exemples

Les exemples suivants utilisent la fonction REDUCE.

Calculer la somme des valeurs d’un tableau

Utilisez la fonction REDUCE pour renvoyer la somme des valeurs d’un tableau et spécifier 0 pour la valeur initiale de l’accumulateur :

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

Cet exemple est le même que l’exemple précédent, mais il spécifie un tableau structuré de type INT :

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

Utilisez la fonction REDUCE pour renvoyer la somme des valeurs d’un tableau et spécifier 10 pour la valeur initiale de l’accumulateur :

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

Calculer la somme du carré de chaque valeur dans un tableau

Utilisez la fonction REDUCE pour renvoyer la somme du carré de chaque valeur du tableau et spécifier 0 pour la valeur initiale de l’accumulateur :

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

Ignorer les valeurs NULL dans un tableau

Dans cet exemple, l’argument array inclut des valeurs NULL. Lorsque ce tableau est transmis à la fonction REDUCE, l’accumulateur aura des valeurs NULL intermédiaires.

Utilisez la fonction REDUCE pour renvoyer la somme des valeurs du tableau et utilisez la fonction IFNULL dans la logique de l’expression lambda pour ignorer les valeurs NULL dans le tableau. L’expression lambda utilise la fonction IFNULL pour traiter chaque valeur du tableau en utilisant la logique suivante :

  • Si acc + val est NULL, alors elle devient acc + 0.

  • Si acc + val n’est pas NULL, alors elle devient acc + val.

Exécutez la requête :

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

Générer des valeurs de chaîne

Utilisez la fonction REDUCE pour renvoyer une liste de valeurs de chaîne en concaténant chaque valeur du tableau :

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

Utiliser un tableau pour l’accumulateur

Utilisez la fonction REDUCE avec la fonction ARRAY_PREPEND dans la logique de l’expression lambda pour renvoyer un tableau qui inverse l’ordre du tableau d’entrée :

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

Utiliser la logique conditionnelle

Utilisez la fonction REDUCE avec la fonction IFF dans la logique de l’expression lambda pour effectuer une action basée sur une logique conditionnelle similaire à une expression if-then. Cet exemple utilise la logique suivante dans l’expression lambda :

  • Si la valeur du tableau est inférieure à sept, mettez-la au carré et ajoutez-la à l’accumulateur.

  • Si la valeur du tableau est supérieure ou égale à sept, ajoutez-la à l’accumulateur sans la mettre au carré.

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

Réduire un tableau d’éléments dans un tableau à une seule valeur

Supposons que vous disposiez d’une table nommée orders avec les colonnes order_id, order_date et order_detail. La colonne order_detail est un tableau contenant les articles, la quantité achetée et le sous-total. La table contient deux lignes de données. L’instruction SQL suivante crée cette table et insère les lignes :

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

Utilisez la fonction REDUCE permettant de renvoyer la somme du sous-total de tous les articles de chaque commande :

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

Utilisez la fonction REDUCE permettant de renvoyer une liste des articles vendus dans chaque commande :

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