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;
+---------------------+
| 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);
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.
Führen Sie ein SELECT auf allen Werten aus:
SELECT * FROM varia;
+--------+-----------------------+--------+
| 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 ...;
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 ...;
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;
+----------+-------------------+----------------------------+
| '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);
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;
+-------------------+
| 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> , ...]] }
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. Dervalue
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;
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 Tabellemy_table
entsprechen:SELECT {* ILIKE 'col1%'} FROM my_table;
Um bestimmte Spalten auszuschließen, verwenden Sie das Schlüsselwort EXCLUDE. Die folgende Abfrage schließt zum Beispiel
col1
in der Tabellemy_table
aus:SELECT {* EXCLUDE col1} FROM my_table;
Die folgende Abfrage schließt
col1
undcol2
in der Tabellemy_table
aus:SELECT {* EXCLUDE (col1, col2)} FROM my_table;
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;
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;
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;
+--------------------------+
| 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;
+------------------+----------+
| 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;
+----------------------------------+
| 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};
+--------------------------------------------------+
| {'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;
+--------------------------+
| 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;
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;
+---------------------------+------------------------+
| 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);
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> , ...]]
Wobei:
value
Der Wert mit einem Arrayelement verbundene Wert Die
value
kann ein Literal oder ein Ausdruck sein. Dervalue
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 ];
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);
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];
+----------------------------------+
| [$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;
+--------------+
| 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;
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;
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;
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 ]
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;
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;
+------+---------+--------+-------+---------+-------------+------------+-------+------------+---------+-------------+----------------+
| 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 } '
||
' } ');
Zeigen Sie nun die Daten in der Tabelle an.
SELECT *
FROM demonstration1
ORDER BY id;
+----+-------------+---------------------+--------------------------+
| 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.