半结构化数据类型

以下 Snowflake 数据类型可以包含其他数据类型:

  • VARIANT(可以包含任何其他数据类型的值)。

  • OBJECT(可以直接包含 VARIANT 值,从而间接包含任何其他数据类型的值,包括其自身)。

  • ARRAY(可以直接包含 VARIANT 值,从而间接包含任何其他数据类型的值,包括其自身)。

我们通常将这些数据类型称为 半结构化 数据类型。严格来说, OBJECT 是这些数据类型中唯一一种本身具有真正 半结构化数据类型 <https://en.wikipedia.org/wiki/Semi-structured_data>`_所有特征的数据类型。但是,组合这些数据类型可以显式表示任意 :ref:`分层数据结构 <label-hierarchical_data>,这些结构可用于加载和操作半结构化格式(例如 JSON、Avro、ORC、Parquet 或 XML)的数据。

备注

有关 *结构化数据类型*(例如,ARRAY[INTEGER]、OBJECT[城市 VARCHAR]或 MAP[VARCHAR、VARCHAR])的信息,请参见 结构化数据类型

本主题介绍了其中每种数据类型。

VARIANT

VARIANT 值可以存储任何其他类型的值,包括 OBJECT 和 ARRAY 值。

VARIANT 值的特征

VARIANT 值的最大未压缩数据可达到 16 MB。但实际上,由于内部开销,最大大小通常较小。最大大小还取决于要存储的对象。

插入 VARIANT 数据

要直接插入 VARIANT 数据,请使用 INSERT INTO ... SELECT。下面的示例展示了如何将 JSON 格式的数据插入到 VARIANT 值中:

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

使用 VARIANT 值

要将值转换为 VARIANT 数据类型,或从该数据类型转换为其他类型,可以使用 CAST 函数、TO_VARIANT 函数或 :: 运算符(例如 expression::VARIANT)进行显式转换。

在某些情况下,可以将值隐式转换为 VARIANT 值。有关详细信息,请参阅 数据类型转换

下面的示例代码演示了如何使用 VARIANT 值,包括如何从 VARIANT 值转换以及如何转换为 VARIANT 值。

创建一个表并插入一个值:

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

第一个 UPDATE 将值从 FLOAT 值转换为 VARIANT 值。第二个 UPDATE 将 VARIANT 值转换为 FLOAT 值。

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

SELECT 所有值:

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

如上例所示,要转换 VARIANT 数据类型的值,请将 VARIANT 值转换为目标数据类型。例如,下面的语句使用 :: 运算符将 VARIANT 转换为 FLOAT:

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

VARIANT 数据存储值和值的数据类型。因此,您可以在表达式中使用 VARIANT 值,其中值的数据类型有效,而无需先转换 VARIANT。例如,如果 VARIANT 列 my_variant_column 包含一个数值,则可以直接将 my_variant_column 乘以另一个数值:

SELECT my_variant_column * 3.14 FROM ...;
Copy

可以使用 TYPEOF 函数检索值的本机数据类型。

默认情况下,从 VARIANT 列检索 VARCHAR、DATE、TIME 和 TIMESTAMP 值时,这些值都会放在双引号内。您可以通过将值显式转换为基础数据类型(例如,从 VARIANT 转换为 VARCHAR)来消除双引号。例如:

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

VARIANT 值可以缺失(包含 SQL NULL),这与 VARIANT null 值不同,后者是用于表示半结构化数据中的 null 值的实际值。VARIANT null 是一个与自身相等的真值。有关更多信息,请参阅 VARIANT null

如果数据是从 JSON 格式加载并存储在 VARIANT 列中,则以下注意事项适用:

  • 对于大多数常规且仅使用原生 JSON 类型(例如字符串和数字)的数据,对关系数据和 VARIANT 列中数据的存储和查询操作的性能非常相似。

  • 对于非原生数据(例如日期和时间戳),在加载到 VARIANT 列时,这些值会以字符串的形式存储。因此,相较于存储在具有相应数据类型的关系列中,对这些值的操作可能较慢,并且还会使用更多的空间。

有关使用 VARIANT 数据类型的更多信息,请参阅 存储在 VARIANT 中的半结构化数据的注意事项

有关查询 VARIANT 列中存储的半结构化数据的更多信息,请参阅 查询半结构化数据

VARIANT 数据的常见用途

VARIANT 数据通常用于以下情况:

  • 您希望通过显式定义包含两个或多个 ARRAYs 或 OBJECTs 的层次结构来创建 分层数据

  • 您希望直接加载 JSON、Avro、ORC 或 Parquet 数据,而无需显式描述数据的分层结构。

    Snowflake 可以将数据从 JSON、Avro、ORC 或 Parquet 格式转换为 ARRAY、OBJECT 和 VARIANT 数据的内部层次结构,并将该分层数据直接存储到 VARIANT 值中。虽然您可以自己手动构建数据层次结构,但让 Snowflake 为您完成通常更容易。

    有关加载和转换半结构化数据的更多信息,请参阅 加载半结构化数据

OBJECT

Snowflake OBJECT 值类似于 `JSON“object”<http://json.org>`__。在其他编程语言中,相应的数据类型通常称为“dictionary”、“hash”或“map”。

OBJECT 值包含键值对。

OBJECT 值的特征

在 Snowflake 半结构化 OBJECT 数据中,每个键都是 VARCHAR,每个值都是 VARIANT 值。

由于 VARIANT 值可以存储任何其他数据类型的值,因此不同的 VARIANT 值(在不同的键值对中)可以具有不同的基础数据类型。例如,OBJECT 值可以以 VARCHAR 值保存人名,以 INTEGER 值保存人的年龄。在下面的示例中,姓名和年龄都转换为 VARIANT 值。

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

以下注意事项适用于 OBJECT 数据:

  • Snowflake 当前不支持显式类型对象。

  • 在键值对中,键不应为空字符串,键和值都不应为 NULL。

  • OBJECT 值的最大长度为 16 MB。

  • OBJECT 值可以包含 半结构化数据 (link removed)。

  • OBJECT 值可用于创建 分层数据结构

备注

Snowflake 还支持结构化 OBJECT 数据类型,允许 VARIANT 值以外的值。结构化 OBJECT 类型还定义了该类型的 OBJECT 值中必须存在的键。有关更多信息,请参阅 结构化数据类型

插入 OBJECT 数据

要直接插入 OBJECT 数据,请使用 INSERT INTO ... SELECT

以下示例使用 OBJECT_CONSTRUCT 函数构造它插入的 OBJECT 值。

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

在每个键值对中,值都显式转换为 VARIANT。在这些情况下,不需要显式类型转换。Snowflake 可以隐式转换为 VARIANT。(有关隐式类型转换的信息,请参阅 数据类型转换。)

您还可以使用 OBJECT 常量指定要插入的 OBJECT 值。有关更多信息,请参阅 OBJECT 常量

OBJECT 常量

常量*(也称为 *字面量)是指固定的数据值。Snowflake 支持使用常量来指定 OBJECT 值。OBJECT 常量用大括号({})分隔。

OBJECT 常量有以下语法:

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

其中:

key

键值对中的键。key 必须是字符串字面量。

value

与键关联的值。value 可以是字面量或表达式。value 可以是任何数据类型。

以下是指定 OBJECT 常量的示例:

  • {} 为空 OBJECT 值。

  • { 'key1': 'value1' , 'key2': 'value2' } 包含 OBJECT 值的指定键值对,使用值的字面量。

  • { 'key1': c1+1 , 'key2': c1+2 } 包含 OBJECT 值的指定键值对,使用值的表达式。

  • {*} 通配符使用属性名称作为键,使用关联值作为值,从而基于指定数据构造 OBJECT 值。

    在对象常量中指定时,通配符可以无限定,也可以使用表名或别名限定。例如,这两个通配符规范都有效:

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

    您可以在对象常量中使用 ILIKE 和 EXCLUDE 关键字。要选择特定列,请使用 ILIKE 关键字。例如,以下查询选择与表 my_table 中的模式 col1% 匹配的列:

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

    要排除特定列,请使用 EXCLUDE 关键字。例如,以下查询排除表 my_table 中的 col1

    SELECT {* EXCLUDE col1} FROM my_table;
    
    Copy

    以下查询排除表 my_table 中的 col1col2

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

    通配符不能与键值对混合。例如,不允许使用以下通配符规范:

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

    一个对象常量中不能使用多个通配符。例如,不允许使用以下通配符规范:

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

以下语句使用 OBJECT 常量和 OBJECT_CONSTRUCT 函数,将 OBJECT 数据插入表中。OBJECT 值包含加拿大两个省的名称和省会城市。

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

以下示例从 FROM 子句获取属性名称和值,使用通配符 ({*}) 插入 OBJECT 数据。首先,创建一个名为 demo_ca_provinces 的表,该表的 VARCHAR 值包含省和省会名称:

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

使用 demo_ca_provinces 表中的数据将对象数据插入 my_object_table

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

以下示例使用表达式表示 OBJECT 常量中的值:

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

SQL 语句使用单引号指定 OBJECT 值内的字符串字面量(如 Snowflake SQL 中的其他位置),但 OBJECT 值内的字符串字面量带双引号显示:

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

通过键访问 OBJECT 值的元素

要检索 OBJECT 值中的值,请在 方括号 中指定键,如下所示:

SELECT my_variant_column['key1'] FROM my_table;
Copy

您也可以使用冒号运算符。以下命令显示,无论使用方括号还是冒号,结果都是相同的:

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

有关冒号运算符的更多信息,请参阅 点表示法,其中介绍了如何使用 :. 运算符访问嵌套数据。

OBJECT 数据的常见用途

当以下一项或多项为 True 时,通常使用 OBJECT 数据:

  • 您有多条数据由字符串标识。例如,如果要按省份名称查找信息,您可能需要使用 OBJECT 值。

  • 您希望将有关数据的信息与数据一起存储;名称(键)不仅是不同的标识符,而且是有意义的。

  • 信息没有自然顺序,或者只能从键中推断出顺序。

  • 数据的结构各不相同,或者数据可能不完整。例如,如果要创建通常包含书名、作者姓名和出版日期的图书目录,但在某些情况下出版日期未知,则可能需要使用 OBJECT 值。

ARRAY

Snowflake 数组类似于许多其他编程语言中的数组。数组包含 0 条或多条数据。通过指定每个元素在数组中的位置来访问每个元素。

数组的特征

半结构化数组中的每个值都是 VARIANT 类型。VARIANT 值可以包含任何其他数据类型的值。

其他数据类型的值可以转换为 VARIANT 值,然后存储在数组中。数组的某些函数(包括 ARRAY_CONSTRUCT)可以为您将值 隐式地转换 为 VARIANT 值。

由于数组存储 VARIANT 值,并且由于 VARIANT 值可以在其中存储其他数据类型,因此数组中值的基础数据类型不必完全相同。但是,在大多数情况下,数据元素属于相同或兼容的类型,因此可以以相同的方式处理所有数据元素。

以下注意事项适用于数组:

  • Snowflake 不支持特定非 VARIANT 类型的元素数组。

  • 声明 Snowflake 数组时不指定元素数。数组可以根据 ARRAY_APPEND 等操作动态增长。Snowflake 目前不支持固定大小的数组。

  • 数组可以包含 NULL 值。

  • 数组中所有值的理论最大组合大小为 16 MB。但是,数组具有内部开销。实际的最大数据大小通常较小,具体取决于元素的数量和值。

备注

Snowflake 还支持结构化数组,它允许 VARIANT 以外类型的元素。有关更多信息,请参阅 结构化数据类型

插入 ARRAY 数据

要直接插入 ARRAY 数据,请使用 INSERT INTO ... SELECT

以下代码使用 ARRAY_CONSTRUCT 函数构造它插入的数组。

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

您还可以使用 ARRAY 常量指定要插入的数组。有关更多信息,请参阅 ARRAY 常量

ARRAY 常量

常量*(也称为 *字面量)是指固定的数据值。Snowflake 支持使用常量来指定 ARRAY 值。ARRAY 常量用方括号([])分隔。

ARRAY 常量有以下语法:

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

其中:

value

与数组元素关联的值。value 可以是字面量或表达式。value 可以是任何数据类型。

以下是指定 ARRAY 常量的示例:

  • [] 为空 ARRAY 值。

  • [ 1 , 'value1' ] 包含 ARRAY 常量的指定值,使用值的字面量。

  • [ c1+1 , c1+2 ] 包含 ARRAY 常量的指定值,使用值的表达式。

以下示例使用 ARRAY 常量来指定要插入的数组。

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

以下语句使用 ARRAY 常量和 ARRAY_CONSTRUCT 函数来执行相同的任务:

UPDATE my_table SET my_array = [ 1, 2 ];

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

以下示例使用表达式表示 ARRAY 常量中的值:

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

SQL 语句使用单引号指定数组内的字符串字面量(如 Snowflake SQL 中的其他位置),但数组内的字符串字面量带双引号显示:

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

通过索引或切片访问数组的元素

数组索引从 0 开始,因此数组中的第一个元素是元素 0。

通过在方括号中指定数组元素的索引号来访问数组中的值。例如,以下查询读取 my_array_column 中存储的数组中位于索引位置 2 的值。

SELECT my_array_column[2] FROM my_table;
Copy

数组可以嵌套。以下查询读取嵌套数组的第零个元素的第零个元素:

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

尝试访问数组末尾之外的元素将返回 NULL。

数组的 切片 是相邻元素的序列(即数组的连续子集)。

您可以通过调用 ARRAY_SLICE 函数来访问数组的切片。例如:

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

ARRAY_SLICE 函数返回从指定的起始元素(上例中的 5)到指定的结束元素(上例中的 10,但不包括 该结束元素)之间的元素。

空数组或空切片通常由一对方括号(中间没有任何内容)表示 ([])。

密集和稀疏阵列

数组可以是 密集 数组或 稀疏 数组。

在密集数组中,元素的索引值从零开始,并且是连续的(0、1、2 等)。但是,在稀疏数组中,索引值可以是非连续的(例如 0、2、5)。值不需要从 0 开始。

如果索引没有相应的元素,则与该索引对应的值称为 undefined。例如,如果稀疏数组有三个元素,并且这些元素位于索引 0、2 和 5 处,则索引 1、3 和 4 处的元素为 undefined

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

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

undefined 元素被视为元素。例如,注意前面的稀疏数组示例,该示例包含索引 0、2 和 5 处的元素(索引 5 之后没有任何元素)。如果读取包含索引 3 和 4 处元素的切片,则输出类似于以下内容:

[ undefined, undefined ]
Copy

尝试访问数组末尾之外的切片会导致得到空数组,而不是 undefined 值的数组。以下 SELECT 语句尝试读取示例稀疏数组中最后一个元素之外的内容:

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

输出是一个空数组:

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

请注意,undefined 与 NULL 不同。数组中的 NULL 值是定义的元素。

在密集数组中,每个元素都会占用存储空间,即使元素的值为 NULL。

在稀疏数组中,undefined 元素不直接占用存储空间。

在密集数组中,索引值的理论范围是从 0 到 16777215。(最大理论元素数为 16777216,因为大小上限为 16 MB [16777216 个字节],最小可能值为 1 个字节。)

在稀疏数组中,索引值的理论范围是从 0 到 231 - 1。但是,由于 16 MB 的限制,稀疏数组不能容纳 231 值。最大理论值数仍限制为 16777216。

(请记住,由于内部开销,密集数组和稀疏数组的实际大小限制至少略小于理论最大值 16 MB。)

您可以使用 ARRAY_INSERT 函数在数组中的特定索引点插入值(保持其他数组元素 undefined)来创建稀疏数组。请注意,由于 ARRAY_INSERT 向右推送元素会更改访问它们所需的索引值,因此您几乎总是要从左到右填充稀疏数组(即从 0 向上,为插入的每个新值增加索引值)。

ARRAY 数据的常见用途

当以下一项或多项为 True 时,通常使用 ARRAY 数据:

  • 存在一个数据集合,集合中每个片段的结构相同或相似。

  • 每条数据都应以类似的方式处理。例如,您可以循环遍历数据,以相同的方式处理每条数据。

  • 数据具有自然顺序,例如按时间顺序排列。

示例

以下示例显示了包含 VARIANT、ARRAY 和 OBJECT 数据的表上 DESC TABLE 命令的输出。

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

此示例演示了如何在表中加载简单值,以及查询表时这些值的外观。

创建表并加载数据:

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

现在显示表中的数据。

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

有关其他示例,请参阅 查询半结构化数据

语言: 中文