Semistrukturierte Datentypen

Die folgenden Snowflake-Datentypen können andere Datentypen enthalten:

  • VARIANT (kann einen Wert eines beliebigen anderen Datentyps enthalten).

  • OBJECT (kann direkt einen VARIANT-Wert enthalten und somit indirekt einen Wert eines beliebigen anderen Datentyps, einschließlich sich selbst).

  • ARRAY (kann direkt einen VARIANT-Wert enthalten und somit indirekt einen Wert eines beliebigen anderen Datentyps, einschließlich sich selbst).

Wir bezeichnen diese Datentypen oft als semistrukturierte Datentypen. Streng genommen ist OBJECT der einzige dieser Datentypen, der für sich genommen alle Merkmale eines echten semistrukturierten Datentyps aufweist. Die Kombination dieser Datentypen ermöglicht jedoch die explizite Darstellung beliebiger hierarchischer Datenstrukturen, die zum Laden und Bearbeiten von Daten in semistrukturierten Formaten (z. B. JSON, Avro, ORC, Parquet oder XML) verwendet werden können.

Bemerkung

Weitere Informationen zu strukturierten Datentypen (z. B. ARRAY(INTEGER), OBJECT(city VARCHAR) oder MAP(VARCHAR, VARCHAR) finden Sie unter Strukturierte Datentypen.

Jeder dieser Datentypen wird im Folgenden genauer beschrieben.

VARIANT

Ein VARIANT Wert kann einen Wert mit einem beliebigen anderen Datentyp, einschließlich OBJECT- und ARRAY-Werte speichern.

Merkmale eines VARIANT-Wertes

Ein VARIANT-Wert kann eine maximale Größe von bis zu 16 MB an unkomprimierten Daten haben. In der Praxis ist die maximale Größe jedoch aufgrund des internen Overheads meist geringer. Die maximale Größe hängt auch von dem zu speichernden Objekt ab.

Einfügen von VARIANT-Daten

Um VARIANT-Daten direkt einzufügen, verwenden Sie INSERT INTO ... SELECT. Das folgende Beispiel zeigt, wie Sie JSON-formatierte Daten in einen VARIANT-Wert einfügen:

CREATE OR REPLACE TABLE variant_insert (v VARIANT);
INSERT INTO variant_insert (v)
  SELECT PARSE_JSON('{"key3": "value3", "key4": "value4"}');
SELECT * FROM variant_insert;
Copy
+---------------------+
| V                   |
|---------------------|
| {                   |
|   "key3": "value3", |
|   "key4": "value4"  |
| }                   |
+---------------------+

Verwendung von VARIANT-Werten

Um einen Wert in oder aus dem Datentyp VARIANT zu konvertieren, können Sie explizit die Funktion CAST, die Funktion TO_VARIANT oder den Operator :: (z. B. expression::VARIANT) verwenden.

In manchen Situationen kann ein Wert implizit in einen VARIANT-Wert umgewandelt werden. Weitere Details dazu finden Sie unter Datentypkonvertierung.

Das folgende Beispiel zeigt, wie Sie einen VARIANT-Wert verwenden, einschließlich der Konvertierung von einem VARIANT-Wert und in einen VARIANT-Wert.

Erstellen Sie eine Tabelle, und fügen Sie einen Wert ein:

CREATE OR REPLACE TABLE varia (float1 FLOAT, v VARIANT, float2 FLOAT);
INSERT INTO varia (float1, v, float2) VALUES (1.23, NULL, NULL);
Copy

Das erste UPDATE konvertiert einen Wert von einem FLOAT-Wert in einen VARIANT-Wert. Die zweite UPDATE wandelt einen VARIANT-Wert in einen FLOAT-Wert um.

UPDATE varia SET v = TO_VARIANT(float1);  -- converts from a FLOAT value to a VARIANT value.
UPDATE varia SET float2 = v::FLOAT;       -- converts from a VARIANT value to a FLOAT value.
Copy

Führen Sie ein SELECT auf allen Werten aus:

SELECT * FROM varia;
Copy
+--------+-----------------------+--------+
| FLOAT1 | V                     | FLOAT2 |
|--------+-----------------------+--------|
|   1.23 | 1.230000000000000e+00 |   1.23 |
+--------+-----------------------+--------+

Wie im vorigen Beispiel gezeigt, konvertieren Sie einen Wert aus dem Datentyp VARIANT, indem Sie den VARIANT-Wert in den Zieldatentyp umwandeln. In der folgenden Anweisung wird zum Beispiel der Operator :: verwendet, um VARIANT in FLOAT umzuwandeln:

SELECT my_variant_column::FLOAT * 3.14 FROM ...;
Copy

VARIANT-Daten speichern sowohl den Wert als auch den Datentyp des Wertes. Daher können Sie VARIANT-Werte in Ausdrücken verwenden, in denen der Datentyp des Wertes gültig ist, ohne vorher eine Umwandlung in VARIANT vornehmen zu müssen. Beispiel: Wenn die VARIANT.Spalte my_variant_column einen numerischen Wert enthält, dann können Sie my_variant_column direkt mit einem anderen numerischen Wert multiplizieren:

SELECT my_variant_column * 3.14 FROM ...;
Copy

Sie können den nativen Datentyp des Wertes mit der Funktion TYPEOF abrufen.

Wenn die VARCHAR-, DATE-, TIME- und TIMESTAMP-Werte von einer VARIANT-Spalte abgerufen werden, sind die Werte standardmäßig von doppelten Anführungszeichen umgeben. Sie können die doppelten Anführungszeichen vermeiden, indem Sie die Werte explizit in die zugrundeliegenden Datentypen umwandeln (z. B. von VARIANT in VARCHAR). Beispiel:

SELECT 'Sample', 'Sample'::VARIANT, 'Sample'::VARIANT::VARCHAR;
Copy
+----------+-------------------+----------------------------+
| 'SAMPLE' | 'SAMPLE'::VARIANT | 'SAMPLE'::VARIANT::VARCHAR |
|----------+-------------------+----------------------------|
| Sample   | "Sample"          | Sample                     |
+----------+-------------------+----------------------------+

Ein VARIANT-Wert kann fehlen (SQL NULL enthalten). Das unterscheidet sich von einem VARIANT-null-Wert, bei dem es sich um einen tatsächlichen Wert handelt, der zur Darstellung eines Nullwerts in semistrukturierten Daten dient. VARIANT-null ist echter Wert, der beim Vergleich mit sich selbst Gleichheit ergibt. Weitere Informationen dazu finden Sie unter VARIANT null.

Wenn die Daten aus dem JSON-Format geladen und in einer VARIANT-Spalte gespeichert wurden, gelten die folgenden Hinweise:

  • Bei Daten, die größtenteils regulär sind und nur native JSON-Typen (wie Zeichenfolgen und Zahlen) nutzen, ist die Leistung bei Speicher- und Abfrageoperationen mit relationalen Daten und Daten in einer VARIANT-Spalte sehr ähnlich.

  • Für nicht-native Daten (wie Datumangaben und Zeitstempel) werden die Werte als Zeichenfolgen gespeichert, wenn sie in eine VARIANT-Spalte geladen werden. Daher können Operationen mit diesen Werten langsamer sein und auch mehr Platz beanspruchen als bei der Speicherung in einer relationalen Spalte mit dem entsprechenden Datentyp.

Weitere Informationen zur Verwendung des Datentyps VARIANT finden Sie unter Hinweise zu in VARIANT gespeicherten semistrukturierten Daten.

Weitere Informationen zur Abfrage von semistrukturierten Daten, die in einer VARIANT-Spalte gespeichert sind, finden Sie unter Abfragen von semistrukturierten Daten.

Häufige Verwendungszwecke für VARIANT-Daten

VARIANT-Daten werden normalerweise verwendet, wenn:

  • Sie möchten hierarchische Daten erstellen, indem Sie explizit eine Hierarchie definieren, die zwei oder mehr ARRAYs oder OBJECTs enthält.

  • Sie möchten JSON-, Avro-, ORC- oder Parquet-Daten direkt laden, ohne die hierarchische Struktur der Daten explizit zu beschreiben.

    Snowflake kann Daten aus dem JSON-, Avro-, ORC- oder Parquet-Format automatisch in eine interne Hierarchie von ARRAY-, OBJECT- und VARIANT-Daten konvertieren und diese hierarchischen Daten direkt in einem VARIANT-Wert speichern. Obwohl Sie die Datenhierarchie manuell selbst erstellen können, ist es in der Regel einfacher, dies Snowflake zu überlassen.

    Weitere Informationen zum Laden und Konvertieren semistrukturierter Daten finden Sie unter Laden von semistrukturierten Daten.

OBJECT

Ein Snowflake-OBJECT-Wert ist vergleichbar mit einem JSON-„Objekt“. In anderen Programmiersprachen wird der entsprechende Datentyp auch als „Wörterbuch“, „Hash“ oder „Map“ bezeichnet.

Ein OBJECT-Wert enthält Schlüssel-Wert-Paare.

Merkmale eines OBJECT-Wertes

In den semistrukturierten OBJECT-Daten von Snowflake ist jeder Schlüssel ein VARCHAR-Typ, und jeder Wert ein VARIANT-Typ.

Da ein VARIANT-Wert einen Wert aller anderen Datentypen speichern kann, können verschiedene VARIANT-Werte (in verschiedenen Schlüssel-Wert-Paaren) verschiedene zugrunde liegende Datentypen haben. Ein OBJECT-Wert kann zum Beispiel den Namen einer Person als VARCHAR-Wert und das Alter einer Person als INTEGER-Wert enthalten. Im folgenden Beispiel werden sowohl der Name als auch das Alter in den VARIANT-Werte umgewandelt.

SELECT OBJECT_CONSTRUCT(
  'name', 'Jones'::VARIANT,
  'age',  42::VARIANT);
Copy

Die folgenden Hinweise gelten für OBJECT-Daten:

  • Snowflake unterstützt derzeit keine explizit typisierten Objekte.

  • In einem Schlüssel-Wert-Paar darf der Schlüssel keine leere Zeichenfolge sein, und weder der Schlüssel noch der Wert dürfen NULL sein.

  • Die maximale Länge eines OBJECT-Wertes beträgt 16 MB.

  • Ein OBJECT-Wert kann semistrukturierte Daten enthalten.

  • Ein OBJECT-Wert kann verwendet werden, um hierarchische Datenstrukturen zu erstellen.

Bemerkung

Snowflake unterstützt auch den strukturierten Datentyp OBJECT, der auch andere Werte als VARIANT zulässt. Ein strukturierter OBJECT-Typ definiert auch die Schlüssel, die in einem OBJECT-Wert dieses Typs vorhanden sein müssen. Weitere Informationen dazu finden Sie unter Strukturierte Datentypen.

Einfügen von OBJECT-Daten

Um OBJECT-Daten direkt einzufügen, verwenden Sie INSERT INTO ... SELECT.

Das folgende Beispiel verwendet die Funktion OBJECT_CONSTRUCT, um den OBJECT-Wert zu konstruieren, den es einfügt.

CREATE OR REPLACE TABLE object_example (object_column OBJECT);
INSERT INTO object_example (object_column)
  SELECT OBJECT_CONSTRUCT('thirteen', 13::VARIANT, 'zero', 0::VARIANT);
SELECT * FROM object_example;
Copy
+-------------------+
| OBJECT_COLUMN     |
|-------------------|
| {                 |
|   "thirteen": 13, |
|   "zero": 0       |
| }                 |
+-------------------+

In jedem Schlüssel-Wert-Paar wurde der Wert explizit in VARIANT umgewandelt. Eine explizite Umwandlung war in diesen Fällen nicht erforderlich. Snowflake kann implizit eine Umwandlung in VARIANT ausführen. (Weitere Informationen zur impliziten Umwandlung finden Sie unter Datentypkonvertierung.)

Sie können auch eine OBJECT-Konstante verwenden, um den einzufügenden OBJECT-Wert anzugeben. Weitere Informationen dazu finden Sie unter OBJECT-Konstanten.

OBJECT-Konstanten

Eine Konstante (auch als Literal bezeichnet) bezieht sich auf einen festen Datenwert. Snowflake unterstützt die Verwendung von Konstanten zur Angabe von OBJECT-Werten. OBJECT-Konstanten werden durch geschweifte Klammern ({ und }) abgegrenzt.

OBJECT-Konstanten haben die folgende Syntax:

{ [<key>: <value> [, <key>: <value> , ...]] }
Copy

Wobei:

key

Der Schlüssel in einem Schlüssel-Wert-Paar. Der key muss eine Zeichenfolge (Literal) sein.

value

Der mit dem Schlüssel verbundene Wert Die value kann ein Literal oder ein Ausdruck sein. Der value kann ein beliebiger Datentyp sein.

Im Folgenden finden Sie Beispiele, die OBJECT-Konstanten angeben:

  • {} ist ein leerer OBJECT-Wert.

  • { 'key1': 'value1' , 'key2': 'value2' } enthält die angegebenen Schlüssel-Wert-Paare für den OBJECT-Wert unter Verwendung von Literalen für die Werte.

  • { 'key1': c1+1 , 'key2': c1+2 } enthält die angegebenen Schlüssel-Wert-Paare für den OBJECT-wert mit Ausdrücken für die Werte.

  • {*} ist ein Platzhalter, der den OBJECT-Wert aus den angegebenen Daten konstruiert, indem er die Attributnamen als Schlüssel und die zugehörigen Werte als Werte verwendet.

    Wenn er in einer Objektkonstante angegeben ist, kann der Platzhalter unqualifiziert oder mit einem Tabellennamen oder Alias qualifiziert sein. Zum Beispiel sind beide dieser Platzhalterspezifikationen gültig:

    SELECT {*} FROM my_table;
    
    SELECT {my_table1.*}
      FROM my_table1 INNER JOIN my_table2
          ON my_table2.col1 = my_table1.col1;
    
    Copy

    Sie können die Schlüsselwörter ILIKE und EXCLUDE in einer Objektkonstante verwenden. Um bestimmte Spalten auszuwählen, verwenden Sie das Schlüsselwort ILIKE. Die folgende Abfrage wählt zum Beispiel Spalten aus, die dem Muster col1% in der Tabelle my_table entsprechen:

    SELECT {* ILIKE 'col1%'} FROM my_table;
    
    Copy

    Um bestimmte Spalten auszuschließen, verwenden Sie das Schlüsselwort EXCLUDE. Die folgende Abfrage schließt zum Beispiel col1 in der Tabelle my_table aus:

    SELECT {* EXCLUDE col1} FROM my_table;
    
    Copy

    Die folgende Abfrage schließt col1 und col2 in der Tabelle my_table aus:

    SELECT {* EXCLUDE (col1, col2)} FROM my_table;
    
    Copy

    Platzhalter können nicht mit Schlüssel-Wert-Paaren gemischt werden. Die folgende Platzhalterspezifikation ist zum Beispiel nicht zulässig:

    SELECT {*, 'k': 'v'} FROM my_table;
    
    Copy

    In einer Objektkonstanten kann nicht mehr als ein Platzhalter verwendet werden. Die folgende Platzhalterspezifikation ist zum Beispiel nicht zulässig:

    SELECT {t1.*, t2.*} FROM t1, t2;
    
    Copy

Die folgenden Anweisungen verwenden eine OBJECT-Konstante und die Funktion OBJECT_CONSTRUCT, um OBJECT-Daten in eine Tabelle einzufügen. Die OBJECT-Werte enthalten die Namen und Hauptstädte von zwei kanadischen Provinzen.

CREATE OR REPLACE TABLE my_object_table (my_object OBJECT);

INSERT INTO my_object_table (my_object)
  SELECT { 'PROVINCE': 'Alberta'::VARIANT , 'CAPITAL': 'Edmonton'::VARIANT };

INSERT INTO my_object_table (my_object)
  SELECT OBJECT_CONSTRUCT('PROVINCE', 'Manitoba'::VARIANT , 'CAPITAL', 'Winnipeg'::VARIANT );

SELECT * FROM my_object_table;
Copy
+--------------------------+
| MY_OBJECT                |
|--------------------------|
| {                        |
|   "CAPITAL": "Edmonton", |
|   "PROVINCE": "Alberta"  |
| }                        |
| {                        |
|   "CAPITAL": "Winnipeg", |
|   "PROVINCE": "Manitoba" |
| }                        |
+--------------------------+

Im folgenden Beispiel wird der Platzhalter ({*}) verwendet, um OBJECT-Daten einzufügen, indem die Attributnamen und -werte aus der FROM-Klausel abgerufen werden. Erstellen Sie zunächst eine Tabelle mit dem Namen demo_ca_provinces mit VARCHAR-Werten, die die Provinz- und Hauptstadtnamen enthalten:

CREATE OR REPLACE TABLE demo_ca_provinces (province VARCHAR, capital VARCHAR);
INSERT INTO demo_ca_provinces (province, capital) VALUES
  ('Ontario', 'Toronto'),
  ('British Columbia', 'Victoria');

SELECT province, capital
  FROM demo_ca_provinces
  ORDER BY province;
Copy
+------------------+----------+
| PROVINCE         | CAPITAL  |
|------------------+----------|
| British Columbia | Victoria |
| Ontario          | Toronto  |
+------------------+----------+

Fügen Sie Objektdaten in die my_object_table ein, indem Sie die Daten aus der Tabelle demo_ca_provinces verwenden:

INSERT INTO my_object_table (my_object)
  SELECT {*} FROM demo_ca_provinces;

SELECT * FROM my_object_table;
Copy
+----------------------------------+
| MY_OBJECT                        |
|----------------------------------|
| {                                |
|   "CAPITAL": "Edmonton",         |
|   "PROVINCE": "Alberta"          |
| }                                |
| {                                |
|   "CAPITAL": "Winnipeg",         |
|   "PROVINCE": "Manitoba"         |
| }                                |
| {                                |
|   "CAPITAL": "Toronto",          |
|   "PROVINCE": "Ontario"          |
| }                                |
| {                                |
|   "CAPITAL": "Victoria",         |
|   "PROVINCE": "British Columbia" |
| }                                |
+----------------------------------+

Das folgende Beispiel verwendet Ausdrücke für die Werte in einer OBJECT-Konstante:

SET my_variable = 10;
SELECT {'key1': $my_variable+1, 'key2': $my_variable+2};
Copy
+--------------------------------------------------+
| {'KEY1': $MY_VARIABLE+1, 'KEY2': $MY_VARIABLE+2} |
|--------------------------------------------------|
| {                                                |
|   "key1": 11,                                    |
|   "key2": 12                                     |
| }                                                |
+--------------------------------------------------+

In SQL-Anweisungen geben Zeichenfolgenliterale innerhalb eines OBJECT mit einfachen Anführungszeichen an (wie in Snowflake SQL üblich), dass aber Zeichenfolgenliterale innerhalb eines OBJECT mit doppelten Anführungszeichen dargestellt werden:

SELECT { 'Manitoba': 'Winnipeg' } AS province_capital;
Copy
+--------------------------+
| PROVINCE_CAPITAL         |
|--------------------------|
| {                        |
|   "Manitoba": "Winnipeg" |
| }                        |
+--------------------------+

Zugriff auf Elemente eines OBJECT-Wertes über den Schlüssel

Um den Wert in einem OBJECT-Wert abzurufen, geben Sie den Schlüssel in eckigen Klammern an, wie unten gezeigt:

SELECT my_variant_column['key1'] FROM my_table;
Copy

Sie können auch den Doppelpunkt-Operator verwenden. Mit dem folgenden Befehl wird gezeigt, dass die Ergebnisse gleich sind, egal ob eckige Klammern oder Doppelpunkte verwendet werden:

SELECT object_column['thirteen'],
       object_column:thirteen
  FROM object_example;
Copy
+---------------------------+------------------------+
| OBJECT_COLUMN['THIRTEEN'] | OBJECT_COLUMN:THIRTEEN |
|---------------------------+------------------------|
| 13                        | 13                     |
+---------------------------+------------------------+

Weitere Informationen zum Doppelpunkt-Operator finden Sie unter Punktierte Schreibweise, wo die Verwendung der Operatoren : und . für den Zugriff auf verschachtelte Daten beschrieben wird.

Häufige Verwendungszwecke für OBJECT-Daten

OBJECT-Daten werden normalerweise verwendet, wenn eine oder mehrere der folgenden Bedingungen erfüllt sind:

  • Sie haben mehrere Datenelemente, die durch Zeichenfolgen identifiziert werden. Wenn Sie z. B. Informationen nach Provinznamen suchen möchten, sollten Sie einen OBJECT-Wert verwenden.

  • Sie möchten Informationen über die Daten zusammen mit den Daten speichern. Die Namen (Schlüssel) dienen nicht nur als eindeutige Bezeichner, sondern sie haben auch eine Bedeutung.

  • Die Informationen haben keine natürliche Reihenfolge, oder die Reihenfolge lässt sich nur aus den Schlüsseln ableiten.

  • Die Struktur der Daten variiert, oder die Daten können unvollständig sein. Wenn Sie z. B. einen Katalog von Büchern erstellen möchten, der normalerweise den Titel, den Namen des Autors und das Erscheinungsdatum enthält, aber in einigen Fällen ist das Erscheinungsdatum unbekannt, dann sollten Sie einen OBJECT-Wert verwenden.

ARRAY

Ein Snowflake-Array ist ähnlich wie ein Array in vielen anderen Programmiersprachen. Ein Array enthält 0 oder mehr Datenelemente. Der Zugriff auf jedes Element erfolgt durch Angabe seiner Position im Array.

Merkmale eines Arrays

Jeder Wert in einem semistrukturierten Array ist vom Typ VARIANT. Ein VARIANT-Wert kann einen Wert eines beliebigen anderen Datentyps enthalten.

Werte anderer Datentypen können in VARIANT-Werte umgewandelt und dann in einem Array gespeichert werden. Einige Funktionen für Arrays, darunter ARRAY_CONSTRUCT, können implizit Werte in VARIANT-Werte umwandeln.

Da in Arrays VARIANT-Werte gespeichert und VARIANT-Werte andere Datentypen enthalten können, müssen die zugrunde liegenden Datentypen der Werte in einem Array nicht identisch sein. In den meisten Fällen haben die Datenelemente jedoch denselben oder einen kompatiblen Typ, sodass sie alle auf dieselbe Weise verarbeitet werden können.

Die folgenden Hinweise gelten für Arrays:

  • Snowflake unterstützt keine Arrays mit Elementen eines bestimmten Nicht-VARIANT-Typs.

  • Ein Snowflake-Array wird ohne Angabe der Anzahl der Elemente deklariert. Ein Array kann auf der Grundlage von Operationen wie ARRAY_APPEND dynamisch wachsen. Snowflake unterstützt derzeit keine Arrays mit fester Größe.

  • Ein Array kann NULL-Werte enthalten.

  • Die theoretische maximale Größe aller Werte in einem Array beträgt 16 MB. Allerdings haben Arrays einen internen Overhead. Die praktische maximale Datengröße ist in der Regel kleiner, abhängig von der Anzahl und den Werten der Elemente.

Bemerkung

Snowflake unterstützt auch strukturierte Arrays, die Elemente von anderen Typen als VARIANT zulassen. Weitere Informationen dazu finden Sie unter Strukturierte Datentypen.

Einfügen von ARRAY-Daten

Um ARRAY-Daten direkt einzufügen, verwenden Sie INSERT INTO ... SELECT.

Der folgende Code verwendet die Funktion ARRAY_CONSTRUCT, um das Array zu erstellen, das er einfügt.

CREATE OR REPLACE TABLE array_example (array_column ARRAY);
INSERT INTO array_example (array_column)
  SELECT ARRAY_CONSTRUCT(12, 'twelve', NULL);
Copy

Sie können auch eine ARRAY-Konstante verwenden, um das einzufügende Array anzugeben. Weitere Informationen dazu finden Sie unter ARRAY-Konstanten.

ARRAY-Konstanten

Eine Konstante (auch als Literal bezeichnet) bezieht sich auf einen festen Datenwert. Snowflake unterstützt die Verwendung von Konstanten zur Angabe von ARRAY-Werten. ARRAY-Konstanten werden durch eckige Klammern ([ und ]) abgegrenzt.

ARRAY-Konstanten haben die folgende Syntax:

[<value> [, <value> , ...]]
Copy

Wobei:

value

Der Wert mit einem Arrayelement verbundene Wert Die value kann ein Literal oder ein Ausdruck sein. Der value kann ein beliebiger Datentyp sein.

Im Folgenden finden Sie Beispiele, die ARRAY-Konstanten angeben:

  • [] ist ein leerer ARRAY-Wert.

  • { 'value1' , 'value2' } enthält die angegebenen Werte für die ARRAY-Konstante unter Verwendung von Literalen für die Werte.

  • { c1+1 , c1+2 } enthält die angegebenen Werte für die ARRAY-Konstante unter Verwendung von Ausdrücken für die Werte.

Das folgende Beispiel verwendet eine ARRAY-Konstante, um das einzufügende Array anzugeben.

INSERT INTO array_example (array_column)
  SELECT [ 12, 'twelve', NULL ];
Copy

Die folgenden Anweisungen verwenden eine ARRAY-Konstante und die Funktion ARRAY_CONSTRUCT, um die gleiche Aufgabe auszuführen:

UPDATE my_table SET my_array = [ 1, 2 ];

UPDATE my_table SET my_array = ARRAY_CONSTRUCT(1, 2);
Copy

Das folgende Beispiel verwendet Ausdrücke für die Werte in einer ARRAY-Konstante:

SET my_variable = 10;
SELECT [$my_variable+1, $my_variable+2];
Copy
+----------------------------------+
| [$MY_VARIABLE+1, $MY_VARIABLE+2] |
|----------------------------------|
| [                                |
|   11,                            |
|   12                             |
| ]                                |
+----------------------------------+

In SQL-Anweisungen geben Zeichenfolgenliterale innerhalb eines Array mit einfachen Anführungszeichen an (wie in Snowflake SQL üblich), dass aber Zeichenfolgenliterale innerhalb eines Arrays mit doppelten Anführungszeichen dargestellt werden:

SELECT [ 'Alberta', 'Manitoba' ] AS province;
Copy
+--------------+
| PROVINCE     |
|--------------|
| [            |
|   "Alberta", |
|   "Manitoba" |
| ]            |
+--------------+

Zugriff auf Elemente eines Arrays per Index oder per Slice

Array-Indizes sind 0-basiert, sodass das erste Element in einem Array das Element 0 ist.

Der Zugriff auf Werte in einem Array erfolgt durch Angabe der Indexnummer eines Arrayelements in eckigen Klammern. Die folgende Abfrage liest zum Beispiel den Wert an der Indexposition 2 in dem Array, das in my_array_column gespeichert ist.

SELECT my_array_column[2] FROM my_table;
Copy

Arrays können verschachtelt werden. Die folgende Abfrage liest das nullte Element aus dem nullten Element eines verschachtelten Arrays:

SELECT my_array_column[0][0] FROM my_table;
Copy

Der Versuch, auf ein Element jenseits des Endes eines Arrays zuzugreifen, liefert NULL.

Ein Slice eines Arrays ist eine Sequenz benachbarter Elemente, d. h. eine zusammenhängende Teilmenge des Arrays.

Sie können auf einen Slices eines Arrays zugreifen, indem Sie die Funktion ARRAY_SLICE aufrufen. Beispiel:

SELECT ARRAY_SLICE(my_array_column, 5, 10) FROM my_table;
Copy

Die Funktion ARRAY_SLICE gibt Elemente vom angegebenen Anfangselement (Element 5 im obigen Beispiel) bis zum aber nicht einschließlich des angegebenen Endelements (Element 10 im obigen Beispiel) zurück.

Ein leeres Array oder ein leeres Slice wird meist durch ein Paar eckiger Klammern mit nichts dazwischen ([]) angegeben.

Dichte und spärliche Arrays

Ein Array kann dicht oder dünnbesetzt sein.

In einem dichten Array beginnen die Indexwerte der Elemente bei 0 und sind sequenziell (0, 1, 2, usw.). In einem dünnbesetzten Array müssen die Indexwerte nicht sequenziell sein (z. B. 0, 2, 5). Die Werte müssen nicht bei 0 beginnen.

Hat ein Index kein entsprechendes Element, so gilt der Wert, der diesem Index entspricht, als undefiniert. Wenn zum Beispiel ein dünnbesetztes Array drei Elemente hat und diese Elemente an den Indizes 0, 2 und 5 liegen, dann sind die Elemente an den Indizes 1, 3 und 4 undefined.

   0            2                  5
+-----+.....+-------+.....+.....+------+
| Ann |     | Carol |     |     | Fred |
+-----+.....+-------+.....+.....+------+

        ^             ^     ^
        |             |     |
        undefined--------------

Ein undefiniertes Element wird wie ein Element behandelt. Betrachten wir zum Beispiel das frühere Beispiel eines dünnbesetzten Arrays, das Elemente bei den Indizes 0, 2 und 5 enthält (und keine Elemente nach Index 5). Wenn Sie den Slice mit den Elementen an den Indizes 3 und 4 lesen, sieht die Ausgabe wie folgt aus:

[ undefined, undefined ]
Copy

Der Versuch, auf einen Slice hinter dem Ende eines Arrays zuzugreifen, führt zu einem leeren Array, nicht zu einem Array mit undefined Werten. Mit der folgenden SELECT-Anweisung wird versucht, über das letzte Element des dünnbesetzten Arrays hinaus zu lesen:

SELECT ARRAY_SLICE(array_column, 6, 8) FROM table_1;
Copy

Die Ausgabe ist ein leeres Array:

+---------------------------------+
| array_slice(array_column, 6, 8) |
+---------------------------------+
| [ ]                             |
+---------------------------------+

Beachten Sie, dass sich undefined von NULL unterscheidet. Ein NULL-Wert in einem Array ist ein definiertes Element.

In einem dichten Array verbraucht jedes Element Speicherplatz, auch wenn der Wert des Elements NULL ist.

In einem dünnbesetzten Array verbrauchen die undefined-Elemente nicht direkt Speicherplatz.

In einem dichten Array liegt der theoretische Bereich der Indexwerte zwischen 0 und 16.777.215. (Die maximale theoretische Anzahl von Elementen ist 16.777.216, da die Obergrenze der Größe 16 MB (16.777.216 Bytes) und der kleinstmögliche Wert ein Byte ist).

In einem dünnbesetzten Array liegt der theoretische Bereich der Indexwerte zwischen 0 und 231 - 1. Aufgrund der 16-MB-Beschränkung kann ein dünnbesetztes Array jedoch keine 231 Werte enthalten. Die maximale theoretische Anzahl von Werten ist immer noch auf 16.777.216 begrenzt.

(Denken Sie daran, dass aufgrund des internen Overheads die praktische Größenbegrenzung sowohl bei dichten als auch bei dünnbesetzten Arrays zumindest geringfügig unter dem theoretischen Maximum von 16 MB liegt).

Sie können ein dünnbesetztes Array erstellen, indem Sie die Funktion ARRAY_INSERT verwenden, um Werte an bestimmten Indexpunkten in ein Array einzufügen (wobei andere Arrayelemente undefined bleiben). Beachten Sie, dass ARRAY_INSERT Elemente nach rechts schiebt, wodurch sich die Indexwerte ändern, die für den Zugriff auf die Elemente erforderlich sind. Daher sollten Sie ein dünnbesetztes Array fast immer von links nach rechts füllen (d. h. von 0 aufwärts, wobei der Indexwert für jeden neu eingefügten Wert erhöht wird).

Häufige Verwendungszwecke für ARRAY-Daten

ARRAY-Daten werden normalerweise verwendet, wenn eine oder mehrere der folgenden Bedingungen erfüllt sind:

  • Es gibt eine Datensammlung, und jedes Element in der Sammlung ist gleich oder ähnlich strukturiert.

  • Alle Daten müssen auf ähnliche Weise verarbeitet werden. Sie könnten zum Beispiel die Daten mit einer Schleife durchlaufen und jedes Element auf dieselbe Weise verarbeiten.

  • Die Daten haben eine natürliche Reihenfolge, zum Beispiel chronologisch.

Beispiele

Das folgende Beispiel zeigt die Ausgabe des Befehls DESC TABLE für eine Tabelle mit VARIANT-, ARRAY- und OBJECT-Daten.

CREATE OR REPLACE TABLE test_semi_structured(
  var VARIANT,
  arr ARRAY,
  obj OBJECT);

DESC TABLE test_semi_structured;
Copy
+------+---------+--------+-------+---------+-------------+------------+-------+------------+---------+-------------+----------------+
| name | type    | kind   | null? | default | primary key | unique key | check | expression | comment | policy name | privacy domain |
|------+---------+--------+-------+---------+-------------+------------+-------+------------+---------+-------------+----------------|
| VAR  | VARIANT | COLUMN | Y     | NULL    | N           | N          | NULL  | NULL       | NULL    | NULL        | NULL           |
| ARR  | ARRAY   | COLUMN | Y     | NULL    | N           | N          | NULL  | NULL       | NULL    | NULL        | NULL           |
| OBJ  | OBJECT  | COLUMN | Y     | NULL    | N           | N          | NULL  | NULL       | NULL    | NULL        | NULL           |
+------+---------+--------+-------+---------+-------------+------------+-------+------------+---------+-------------+----------------+

In diesem Beispiel wird gezeigt, wie Sie einfache Werte in die Tabelle laden und wie diese Werte aussehen, wenn Sie die Tabelle abfragen.

Erstellen Sie eine Tabelle, und Laden Sie die Daten:

CREATE TABLE demonstration1 (
  ID INTEGER,
  array1 ARRAY,
  variant1 VARIANT,
  object1 OBJECT);

INSERT INTO demonstration1 (id, array1, variant1, object1) 
  SELECT 
    1, 
    ARRAY_CONSTRUCT(1, 2, 3), 
    PARSE_JSON(' { "key1": "value1", "key2": "value2" } '),
    PARSE_JSON(' { "outer_key1": { "inner_key1A": "1a", "inner_key1B": "1b" }, '
              ||
               '   "outer_key2": { "inner_key2": 2 } } ');

INSERT INTO demonstration1 (id, array1, variant1, object1) 
  SELECT 
    2,
    ARRAY_CONSTRUCT(1, 2, 3, NULL), 
    PARSE_JSON(' { "key1": "value1", "key2": NULL } '),
    PARSE_JSON(' { "outer_key1": { "inner_key1A": "1a", "inner_key1B": NULL }, '
              ||
               '   "outer_key2": { "inner_key2": 2 } '
              ||
               ' } ');
Copy

Zeigen Sie nun die Daten in der Tabelle an.

SELECT * 
  FROM demonstration1
  ORDER BY id;
Copy
+----+-------------+---------------------+--------------------------+
| ID | ARRAY1      | VARIANT1            | OBJECT1                  |
|----+-------------+---------------------+--------------------------|
|  1 | [           | {                   | {                        |
|    |   1,        |   "key1": "value1", |   "outer_key1": {        |
|    |   2,        |   "key2": "value2"  |     "inner_key1A": "1a", |
|    |   3         | }                   |     "inner_key1B": "1b"  |
|    | ]           |                     |   },                     |
|    |             |                     |   "outer_key2": {        |
|    |             |                     |     "inner_key2": 2      |
|    |             |                     |   }                      |
|    |             |                     | }                        |
|  2 | [           | {                   | {                        |
|    |   1,        |   "key1": "value1", |   "outer_key1": {        |
|    |   2,        |   "key2": null      |     "inner_key1A": "1a", |
|    |   3,        | }                   |     "inner_key1B": null  |
|    |   undefined |                     |   },                     |
|    | ]           |                     |   "outer_key2": {        |
|    |             |                     |     "inner_key2": 2      |
|    |             |                     |   }                      |
|    |             |                     | }                        |
+----+-------------+---------------------+--------------------------+

Weitere Beispiele finden Sie unter Abfragen von semistrukturierten Daten.