構造化データ型

構造化型は、特定の Snowflakeデータ型 を持つ要素またはキーと値のペアを含む ARRAY、 OBJECT、 MAP です。以下は構造化型の例です。

  • INTEGER 要素の ARRAY。

  • VARCHAR および NUMBER のキーと値のペアを含む OBJECT。

  • VARCHAR キーを DOUBLE 値に関連付ける MAP。

構造化型は次の方法で使用できます。

  • Icebergテーブル に構造化型の列を定義できます。

    Icebergデータ型 liststructmap は、Snowflakeの構造化 ARRAY、構造化 OBJECT、 MAP 型に対応します。

  • Icebergテーブルの構造化型列のデータにアクセスする場合は、構造化型を使用します。

  • 半構造化の ARRAYOBJECTVARIANT を、対応する構造化型にキャストできます(例: ARRAY を INTEGER 要素の ARRAY にキャスト)。半構造化型の構造化型をキャストすることもできます。

注釈

現在、Icebergテーブル以外のテーブルは構造化型をサポートしていません。構造化型の列を通常のテーブルに追加することはできません。

このトピックでは、Snowflakeでの構造化型の使用方法について説明します。

構造化型の指定

構造化型の列を定義する場合、または値を構造化型にキャストする場合、次のセクションで説明する構文を使用します。

構造化 ARRAY の指定

構造化 ARRAY を指定するには、次の構文を使用します。

ARRAY( <element_type> [ NOT NULL ] )
Copy

条件:

  • element_type はこの ARRAY の要素の Snowflakeデータ型 です。

    要素の型として、構造化 ARRAY、構造化 OBJECT、または MAP を指定することもできます。

    注釈

    Icebergテーブル列の定義では、 ARRAY 要素の型として VARIANT、半構造化 ARRAY、または半構造化 OBJECT を指定することはできません。

  • NOT NULL は ARRAY が NULL の要素を含むことができないことを指定します。

例えば、次のステートメントで SYSTEM$TYPEOF 関数が返す型を比較します。

  • 最初の列式は、半構造化 ARRAY を構造化 ARRAY (NUMBER 要素の ARRAY)にキャストします。

  • 2番目の列式は半構造化 ARRAY を指定します。

SELECT
  SYSTEM$TYPEOF(
    [1, 2, 3]::ARRAY(NUMBER)
  ) AS structured_array,
  SYSTEM$TYPEOF(
    [1, 2, 3]
  ) AS semi_structured_array;
Copy
+-------------------------------+-----------------------+
| STRUCTURED_ARRAY              | SEMI_STRUCTURED_ARRAY |
|-------------------------------+-----------------------|
| ARRAY(NUMBER(38,0))[LOB]      | ARRAY[LOB]            |
+-------------------------------+-----------------------+

構造化 OBJECT の指定

構造化 OBJECT を指定するには、次の構文を使用します。

OBJECT(
  [
    <key> <value_type> [ NOT NULL ]
    [ , <key> <value_type> [ NOT NULL ] ]
    [ , ... ]
  ]
)
Copy

条件:

  • key は OBJECT のキーを指定します。

    • オブジェクト定義の各 key は一意である必要があります。

    • キーの順序はオブジェクト定義の一部です。同じキーを持つ2つの OBJECTs を異なる順序で比較することは許可されていません。(コンパイル時にエラーが発生します)。

    • キーを指定せずに括弧を指定した場合(つまり OBJECT() を使用した場合)、結果として得られる型は、キーを含まない構造化 OBJECT になります。キーを持たない構造化 OBJECT は、半構造化 OBJECT とは異なります。

  • value_type は、キーに対応する値の Snowflakeデータ型 です。

    値の型として、構造化 ARRAY、構造化 OBJECT、または MAP を指定することもできます。

    注釈

    Icebergテーブルの列の定義では、 OBJECT キーに対応する値の型として VARIANT、半構造化 ARRAY、または半構造化 OBJECT を指定することはできません。

  • NOT NULL は、キーに対応する値は NULL にできないことを指定します。

例えば、次のステートメントで SYSTEM$TYPEOF 関数が返す型を比較します。

  • 最初の列式は、半構造化 OBJECT を、以下のキーと値を含む構造化 OBJECT にキャストします。

    • NULL ではない VARCHAR 値を持つ str という名前のキー。

    • NUMBER 値を持つ num という名前のキー。

  • 2番目の列式は半構造化 OBJECT を指定します。

SELECT
  SYSTEM$TYPEOF(
    {
      'str': 'test',
      'num': 1
    }::OBJECT(
      str VARCHAR NOT NULL,
      num NUMBER
    )
  ) AS structured_object,
  SYSTEM$TYPEOF(
    {
      'str': 'test',
      'num': 1
    }
  ) AS semi_structured_object;
Copy
+----------------------------------------------------------------+------------------------+
| STRUCTURED_OBJECT                                              | SEMI_STRUCTURED_OBJECT |
|----------------------------------------------------------------+------------------------|
| OBJECT(str VARCHAR(16777216), num NUMBER(38,0) NOT NULL )[LOB] | OBJECT[LOB]            |
+----------------------------------------------------------------+------------------------+

MAP の指定

MAP を指定するには、次の構文を使用します。

MAP( <key_type> , <value_type> [ NOT NULL ] )
Copy

条件:

  • key_type は、マップの Snowflake データ型 のキーです。次のいずれかの型をキーに使用する必要があります。

    • VARCHAR

    • スケール0の NUMBER

    浮動小数点データ型をキーの型として使うことはできません。

    マップのキーは NULL にはできないことに注意してください。

  • value_type は、マップ内の値の Snowflakeデータ型 です。

    値の型として、構造化 ARRAY、構造化 OBJECT、または MAP を指定することもできます。

    注釈

    Icebergテーブル列の定義では、MAP の値の型として VARIANT、半構造化 ARRAY、または半構造化 OBJECT を指定することはできません。

  • NOT NULL は、キーに対応する値は NULL にできないことを指定します。NOT NULL は値を NULL にできないことを指定します。

次の例では、半構造化 OBJECT を MAP にキャストし、 SYSTEM$TYPEOF 関数を使用してその結果のオブジェクトの型を表示します。MAP は VARCHAR キーと VARCHAR 値を関連付けます。

SELECT
  SYSTEM$TYPEOF(
    {
      'a_key': 'a_val',
      'b_key': 'b_val'
    }::MAP(VARCHAR, VARCHAR)
  ) AS map_example;
Copy
+------------------------------------------------+
| MAP_EXAMPLE                                    |
|------------------------------------------------|
| map(VARCHAR(16777216), VARCHAR(16777216))[LOB] |
+------------------------------------------------+

半構造化型での構造化型の使用

VARIANT、半構造化 OBJECT、または半構造化 ARRAY 内で、MAP、構造化 OBJECT、構造化 ARRAY は使用できません。次のような場合にエラーが発生します。

構造化型と半構造化型の変換

次の表は、構造化 OBJECTs、構造化 ARRAYs、および MAPs を OBJECTs、ARRAYs、および VARIANTs (またはその逆)に 変換する ルールをまとめたものです。

ソースデータ型

ターゲットデータ型

キャスト可能

強制可能

半構造化 ARRAY

構造化 ARRAY

半構造化 OBJECT

  • 構造化 OBJECT

  • MAP

半構造化 VARIANT

  • 構造化 ARRAY

  • 構造化 OBJECT

  • MAP

構造化 ARRAY

半構造化 ARRAY

  • 構造化 OBJECT

  • MAP

半構造化 OBJECT

  • 構造化 ARRAY

  • 構造化 OBJECT

  • MAP

半構造化 VARIANT

次のセクションでは、これらのルールについて詳しく説明します。

半構造化型を構造化型に明示的にキャストする

半構造化オブジェクトを構造化型に明示的にキャストするには、 CAST 関数を呼び出すか、::演算子を使用 できます。

注釈

TRY_CAST は構造化型ではサポートされていません。

次の半構造化オブジェクトは、対応する構造化型にのみキャストできます。それ以外の場合は、ランタイムエラーが発生します。

半構造化型

キャスティングできる構造化型

ARRAY

構造化 ARRAY

OBJECT

MAP または構造化 OBJECT

VARIANT

MAP、構造化 ARRAY または OBJECT

次のセクションでは、どのように型がキャスティングされるかについて詳しく説明します。

半構造化 ARRAYs と VARIANTs の構造化 ARRAYs へのキャスト

次のステップは、半構造化 ARRAY または VARIANT を NUMBER 要素の ARRAY にキャストする方法を示しています。

SELECT
  SYSTEM$TYPEOF(
    CAST ([1,2,3] AS ARRAY(NUMBER))
  ) AS array_cast_type,
  SYSTEM$TYPEOF(
    CAST ([1,2,3]::VARIANT AS ARRAY(NUMBER))
  ) AS variant_cast_type;
Copy

または、

SELECT
  SYSTEM$TYPEOF(
    [1,2,3]::ARRAY(NUMBER)
  ) AS array_cast_type,
  SYSTEM$TYPEOF(
    [1,2,3]::VARIANT::ARRAY(NUMBER)
  ) AS variant_cast_type;
Copy
+--------------------------+--------------------------+
| ARRAY_CAST_TYPE          | VARIANT_CAST_TYPE        |
|--------------------------+--------------------------|
| ARRAY(NUMBER(38,0))[LOB] | ARRAY(NUMBER(38,0))[LOB] |
+--------------------------+--------------------------+

半構造化 ARRAY または VARIANT を構造化 ARRAY にキャストする場合、次の点に注意してください。

  • ARRAY の各要素は ARRAY の指定された型にキャストされます。

    ARRAY 列を ARRAY(VARCHAR) にキャストすると、各値は VARCHAR に変換されます。

    SELECT
      CAST ([1,2,3] AS ARRAY(VARCHAR)) AS varchar_array,
      SYSTEM$TYPEOF(varchar_array) AS array_cast_type;
    
    Copy
    +---------------+-------------------------------+
    | VARCHAR_ARRAY | ARRAY_CAST_TYPE               |
    |---------------+-------------------------------|
    | [             | ARRAY(VARCHAR(16777216))[LOB] |
    |   "1",        |                               |
    |   "2",        |                               |
    |   "3"         |                               |
    | ]             |                               |
    +---------------+-------------------------------+
    
  • 要素を指定された型にキャストできない(例えば、 ['a', 'b', 'c'] を ARRAY(NUMBER) にキャストする)場合、キャストは失敗します。

  • ARRAY が NULL 要素を含んでいて、ARRAY 型が NOT NULL を指定している(例えば、 [1, NULL, 3] を ARRAY(NUMBER NOT NULL) にキャストする)場合、キャストは失敗します。

  • JSON null値 である要素は、ターゲット要素型が JSON nullをサポートしていない場合(つまり、ターゲット型が半構造化 ARRAY、OBJECT、VARIANT ではない場合)、NULL に変換されます。

    例えば、ARRAY(NUMBER) にキャストする場合、NUMBER は JSON nullをサポートしていないため、JSON null値は NULL に変換されます。

    一方で、ARRAY(VARIANT) にキャストする場合、VARIANT は JSON nullをサポートしているため、JSON null値は NULL に変換されません。

半構造化 OBJECTs と VARIANTs の構造化 OBJECTs へのキャスト

次のステップは、半構造化 OBJECT または VARIANT を、 citystate のキーと値のペア(これは VARCHAR 値です)を含む構造化 OBJECT にキャストする方法を示しています。

SELECT
  SYSTEM$TYPEOF(
    CAST ({'city':'San Mateo','state':'CA'} AS OBJECT(city VARCHAR, state VARCHAR))
  ) AS object_cast_type,
  SYSTEM$TYPEOF(
    CAST ({'city':'San Mateo','state':'CA'}::VARIANT AS OBJECT(city VARCHAR, state VARCHAR))
  ) AS variant_cast_type;
Copy

または、

SELECT
  SYSTEM$TYPEOF(
     {'city':'San Mateo','state':'CA'}::OBJECT(city VARCHAR, state VARCHAR)
  ) AS object_cast_type,
  SYSTEM$TYPEOF(
     {'city':'San Mateo','state':'CA'}::VARIANT::OBJECT(city VARCHAR, state VARCHAR)
  ) AS variant_cast_type;
Copy
+--------------------------------------------------------------+--------------------------------------------------------------+
| OBJECT_CAST_TYPE                                             | VARIANT_CAST_TYPE                                            |
|--------------------------------------------------------------+--------------------------------------------------------------|
| OBJECT(city VARCHAR(16777216), state VARCHAR(16777216))[LOB] | OBJECT(city VARCHAR(16777216), state VARCHAR(16777216))[LOB] |
+--------------------------------------------------------------+--------------------------------------------------------------+

半構造化 OBJECT または VARIANT を構造化 OBJECT にキャストする場合、次の点に注意してください。

  • OBJECT には、OBJECT 型で指定されていない追加のキーを含むことはできません。

    追加のキーがある場合、キャストは失敗します。

  • OBJECT に OBJECT 型で指定されているキーがない場合、キャストは失敗します。

  • OBJECT の各キーの値は、そのキーに対して指定された型に変換されます。

    値が指定された型にキャストできない場合、キャストは失敗します。

  • キーの値が JSON null値 の場合、ターゲット値の型が JSON nullをサポートしていない(つまり、ターゲット型が半構造化 ARRAY、OBJECT、VARIANTではない)場合、値は NULL に変換されます。

    例えば、OBJECT(city VARCHAR) にキャストする場合、VARCHAR は JSON nullをサポートしていないため、JSON null値は NULL に変換されます。

    一方で、OBJECT(city VARIANT) にキャストする場合、VARIANT は JSON nullをサポートしているため、JSON null値は NULL に変換されません。

半構造化 OBJECTs と VARIANTs の MAPs へのキャスト

次のステートメントは、半構造化 OBJECT または VARIANT を VARCHAR キーと VARCHAR 値を関連付ける MAP にキャストする方法を示しています。

SELECT
  SYSTEM$TYPEOF(
    CAST ({'my_key':'my_value'} AS MAP(VARCHAR, VARCHAR))
  ) AS map_cast_type,
  SYSTEM$TYPEOF(
    CAST ({'my_key':'my_value'} AS MAP(VARCHAR, VARCHAR))
  ) AS variant_cast_type;
Copy

または、

SELECT
  SYSTEM$TYPEOF(
    {'my_key':'my_value'}::MAP(VARCHAR, VARCHAR)
  ) AS map_cast_type,
  SYSTEM$TYPEOF(
    {'my_key':'my_value'}::VARIANT::MAP(VARCHAR, VARCHAR)
  ) AS variant_cast_type;
Copy
+------------------------------------------------+------------------------------------------------+
| MAP_CAST_TYPE                                  | VARIANT_CAST_TYPE                              |
|------------------------------------------------+------------------------------------------------|
| map(VARCHAR(16777216), VARCHAR(16777216))[LOB] | map(VARCHAR(16777216), VARCHAR(16777216))[LOB] |
+------------------------------------------------+------------------------------------------------+

半構造化 OBJECT または VARIANT を MAP にキャストする場合は、次の点に注意してください。

  • キーと値が指定された型と一致しない場合、キーと値は指定された型に変換されます。

  • キーと値が指定された型にキャストできない場合、キャストは失敗します。

  • キーの値が JSON null値 の場合、ターゲット値の型が JSON nullをサポートしていない(つまり、ターゲット型が半構造化 ARRAY、OBJECT、VARIANTではない)場合、値は NULL に変換されます。

    例えば、MAP(VARCHAR, VARCHAR) にキャストする場合、VARCHAR は JSON nullをサポートしていないため、JSON null値は NULL に変換されます。

    一方で、MAP(VARCHAR, VARIANT) にキャストする場合、VARIANT は JSON nullをサポートしているため、JSON null値は NULL に変換されません。

構造化型を半構造化型に明示的にキャストする

構造化型を半構造化型に明示的にキャストするには、 CAST 関数を呼び出すか、::演算子を使用するか、変換関数の1つ(例えば、 TO_ARRAYTO_OBJECTTO_VARIANT)を呼び出します。

注釈

TRY_CAST は構造化型ではサポートされていません。

構造化型

キャスティングできる半構造化型

構造化 ARRAY

ARRAY

MAP または構造化 OBJECT

OBJECT

MAP、構造化 ARRAY、または構造化 OBJECT

VARIANT

例:

  • col_structured_array が ARRAY(VARCHAR) の場合、

    • CAST(col_structured_array AS ARRAY) は半構造化 ARRAY を返します。

    • CAST(col_structured_array AS VARIANT) は半構造化 ARRAY を保持する VARIANT を返す。

  • col_structured_object が OBJECT(name VARCHAR, state VARCHAR) の場合、

    • CAST(col_structured_object AS OBJECT) は半構造化 OBJECT を返します。

    • CAST(col_structured_object AS VARIANT) は半構造化 OBJECT を保持する VARIANT を返します。

  • col_map が MAP(VARCHAR, VARCHAR) の場合、

    • CAST(col_map AS OBJECT) は半構造化 OBJECT を返します。

    • CAST(col_map AS VARIANT) は半構造化 OBJECT を保持する VARIANT を返します。

次の点に注意してください。

  • 半構造化 OBJECT にキャストする場合、構造化 OBJECT 内のキーの順序は保持されません。

  • 構造化 OBJECT または MAP を半構造化 OBJECT または VARIANT にキャストする場合、NULL 値はすべて JSON null値 に変換されます。

    構造化 ARRAY を VARIANT にキャストする場合、NULL の値はそのまま保持されます。

    SELECT [1,2,NULL,3]::ARRAY(INTEGER)::VARIANT;
    
    Copy
    +---------------------------------------+
    | [1,2,NULL,3]::ARRAY(INTEGER)::VARIANT |
    |---------------------------------------|
    | [                                     |
    |   1,                                  |
    |   2,                                  |
    |   undefined,                          |
    |   3                                   |
    | ]                                     |
    +---------------------------------------+
    
  • キーに NUMBER 型を使用する MAP をキャストする場合、MAP キーは返される OBJECT 内で文字列に変換されます。

値の暗黙のキャスト(強制)

ある構造化型から別の構造化型への 暗黙のキャスト(強制) には次のルールが適用されます。

  • 構造化型は、2つの基本オブジェクト型が同じであれば、別の構造化型に強制することができます。

    • 1つの型の ARRAY は、最初の要素型が2番目の要素型に強制可能であれば、別の型の ARRAY に強制することができます。

      要素型は次のいずれかの場合で別の要素型に強制できます。

      • どちらの型も数値である。次のケースがサポートされています。

        • どちらも同じ数値型を使用しているけれども、精度やスケールが異なる可能性がある。

        • NUMBER を FLOAT に強制する(逆も同様)。

      • どちらの型もタイムスタンプである。次のケースがサポートされています。

        • どちらも同じ型を使用しているけれども、精度が異なる可能性がある。

        • TIMESTAMP_LTZ を TIMESTAMP_TZ に強制する(逆も同様)。

      例:

      • ARRAY(NUMBER) を ARRAY(DOUBLE) に強制できる。

      • ARRAY(DATE) を ARRAY(NUMBER) に強制できない。

    • 1つの型定義を持つ OBJECT を、別の型定義を持つ OBJECT に強制することができるのは、次のすべてが正しい場合に限られます。

      • どちらの OBJECT 型も同じ数のキーを持っている。

      • どちらの OBJECT 型もキーに同じ名前を使用している。

      • 両方の OBJECT 型のキーが同じ順番である。

      • 一方の OBJECT 型の各値の型は、もう一方の OBJECT 型の対応する値の型に強制することができる。

        構造化 ARRAYs の要素型の場合と同様に、ある値の型を別の型に強制できるのは次の場合だけです。

        • どちらの型も数値である。次のケースがサポートされています。

          • どちらも同じ数値型を使用しているけれども、精度やスケールが異なる可能性がある。

          • NUMBER を FLOAT に強制する(逆も同様)。

        • どちらの型もタイムスタンプである。次のケースがサポートされています。

          • どちらも同じ型を使用しているけれども、精度が異なる可能性がある。

          • TIMESTAMP_LTZ を TIMESTAMP_TZ に強制する(逆も同様)。

      例:

      • OBJECT(city VARCHAR, zipcode NUMBER) を OBJECT(city VARCHAR, zipcode DOUBLE) に強制することができる。

      • OBJECT(city VARCHAR, zipcode NUMBER) を OBJECT(city VARCHAR, zipcode DATE) に強制することはできない。

    • 1つの値型を持つ MAP は、次の場合に異なる値型を持つ MAP に強制することができる。

      • どちらも数値型である。次のケースがサポートされています。

        • どちらも同じ数値型を使用しているけれども、精度やスケールが異なる可能性がある。

        • NUMBER を FLOAT に強制する(逆も同様)。

      • どちらの値もタイムスタンプである。次のケースがサポートされています。

        • どちらも同じ型を使用しているけれども、精度が異なる可能性がある。

        • TIMESTAMP_LTZ を TIMESTAMP_TZ に強制する(逆も同様)。

      例えば、MAP(VARCHAR, NUMBER) をMAP(VARCHAR, DOUBLE) に強制することができます。

    • 1つのキー型を持つ MAP は、両方のキー型が精度のみが異なる同じ整数 NUMERIC 型を使用する場合に異なるキー型を持つ MAP に強制することができます。

      例えば、MAP(VARCHAR, NUMBER) をMAP(NUMBER, NUMBER) に強制することはできません。

  • 構造化型を半構造化オブジェクトに強制することはできない(その逆も同様)。

  • 値 VARCHAR を構造化型に強制することはできない。

ある構造化型から別の構造型へのキャスト

ある構造化型から別の構造化型にキャストするには、 CAST 関数を呼び出すか、::演算子 を使用します。次の構造化型から、または構造化型へキャストできます。

注釈

TRY_CAST は構造化型ではサポートされていません。

一方の型からもう一方の型に値をキャストできない場合、キャストは失敗します。例えば、ARRAY(BOOLEAN) を ARRAY(DATE) にキャストしようとすると失敗します。

例: ある型の ARRAY から別の型へのキャスト

次の例は ARRAY(NUMBER) を ARRAY(VARCHAR) にキャストします。

SELECT CAST(
  CAST([1,2,3] AS ARRAY(NUMBER))
  AS ARRAY(VARCHAR)
);
Copy

例: OBJECT 内のキーと値のペアの順序の変更

次の例は、構造化 OBJECT 内のキーと値のペアの順序を変更します。

SELECT CAST(
  {'city': 'San Mateo','state': 'CA'}::OBJECT(city VARCHAR, state VARCHAR)
  AS OBJECT(state VARCHAR, city VARCHAR)
);
Copy

例: OBJECT 内のキー名の変更

構造化 OBJECT のキー名を変更するには、 CAST の最後に RENAME FIELDS キーワードを指定します。例:

SELECT CAST({'city':'San Mateo','state': 'CA'}::OBJECT(city VARCHAR, state VARCHAR)
  AS OBJECT(city_name VARCHAR, state_name VARCHAR) RENAME FIELDS);
Copy
+------------------------------------------------------------------------------+
| CAST({'CITY':'SAN MATEO','STATE': 'CA'}::OBJECT(CITY VARCHAR, STATE VARCHAR) |
|   AS OBJECT(CITY_NAME VARCHAR, STATE_NAME VARCHAR) RENAME FIELDS)            |
|------------------------------------------------------------------------------|
| {                                                                            |
|   "city_name": "San Mateo",                                                  |
|   "state_name": "CA"                                                         |
| }                                                                            |
+------------------------------------------------------------------------------+

例: OBJECT へのキーの追加

キャスト先の型に、オリジナルの構造化オブジェクトには存在しない追加のキーと値のペアがある場合は、 ADD FIELDS キーワードを CAST の末尾に指定します。例:

SELECT CAST({'city':'San Mateo','state': 'CA'}::OBJECT(city VARCHAR, state VARCHAR)
  AS OBJECT(city VARCHAR, state VARCHAR, zipcode NUMBER) ADD FIELDS);
Copy
+------------------------------------------------------------------------------+
| CAST({'CITY':'SAN MATEO','STATE': 'CA'}::OBJECT(CITY VARCHAR, STATE VARCHAR) |
|   AS OBJECT(CITY VARCHAR, STATE VARCHAR, ZIPCODE NUMBER) ADD FIELDS)         |
|------------------------------------------------------------------------------|
| {                                                                            |
|   "city": "San Mateo",                                                       |
|   "state": "CA",                                                             |
|   "zipcode": null                                                            |
| }                                                                            |
+------------------------------------------------------------------------------+

新しく追加されたキーの値は NULL に設定されます。これらのキーに値を割り当てる場合は、 OBJECT_INSERT 関数を代わりに呼び出します。

構造化 ARRAYs、構造化 OBJECTs、および MAPs の構築

次のセクションでは、構造化 ARRAYs、構造化 OBJECTs、MAPs の構築方法を説明します。

SQL 関数を使用した構造化 ARRAYs と OBJECTs の構築

次の関数は半構造化 ARRAYs を構築します。

次の関数は半構造化 OBJECTs を構築します。

構造化 ARRAY または OBJECT を構築するには、これらの関数を使用し、関数の戻り値を明示的にキャストします。例:

SELECT ARRAY_CONSTRUCT(10, 20, 30)::ARRAY(NUMBER);
Copy
SELECT OBJECT_CONSTRUCT(
  'name', 'abc',
  'created_date', '2020-01-18'::DATE
)::OBJECT(
  name VARCHAR,
  created_date DATE
);
Copy

詳細については、 半構造化型を構造化型に明示的にキャストする をご参照ください。

注釈

これらの関数に構造化 ARRAYs、構造化 OBJECTs、または MAPs を渡すことはできません。そうすると、構造化型が暗黙のうちに半構造化型にキャストされることになり、これは(値の暗黙のキャスト(強制) で述べたように)許されません。

ARRAY と OBJECT 定数を使用した構造化 ARRAYs と OBJECTs の構築

ARRAY 定数 または OBJECT 定数 を指定する場合、半構造化 ARRAY または OBJECT を指定していることになります。

構造化 ARRAY または OBJECT を構築するには、式を明示的にキャストする必要があります。例:

SELECT [10, 20, 30]::ARRAY(NUMBER);
Copy
SELECT {
  'name': 'abc',
  'created_date': '2020-01-18'::DATE
}::OBJECT(
  name VARCHAR,
  created_date DATE
);
Copy

詳細については、 半構造化型を構造化型に明示的にキャストする をご参照ください。

MAP の構築

MAP を構築するには、半構造化オブジェクトを構築し、 OBJECT を MAP にキャストします。

例えば、次のステートメントはどちらも MAP {'city'->'San Mateo','state'->'CA'} を生成します。

SELECT OBJECT_CONSTRUCT(
  'city', 'San Mateo',
  'state', 'CA'
)::MAP(
  VARCHAR,
  VARCHAR
);
Copy
SELECT {
  'city': 'San Mateo',
  'state': 'CA'
}::MAP(
  VARCHAR,
  VARCHAR
);
Copy

次のステートメントは MAP {-10->'CA',-20->'OR'} を生成します。

SELECT {
  '-10': 'CA',
  '-20': 'OR'
}::MAP(
  NUMBER,
  VARCHAR
)
Copy

詳細については、 半構造化 OBJECTs と VARIANTs の MAPs へのキャスト をご参照ください。

構造化型でのキー、値、要素の操作

次のセクションでは、構造化型で値と要素を使用する方法について説明します。

構造化 OBJECT からのキーのリストの取得

構造化 OBJECT のキーのリストを取得するには、 OBJECT_KEYS 関数を呼び出します。

SELECT OBJECT_KEYS({'city':'San Mateo','state':'CA'}::OBJECT(city VARCHAR, state VARCHAR));
Copy

入力値が構造化 OBJECT の場合、この関数はキーを含む ARRAY(VARCHAR) を返します。入力値が半構造化 OBJECT の場合、この関数は ARRAY を返します。

MAP からのキーのリストの取得

MAP 内のキーのリストを取得するには、 MAP_KEYS 関数を呼び出します。

SELECT MAP_KEYS({'my_key':'my_value'}::MAP(VARCHAR,VARCHAR));
Copy

構造化型からの値と要素へのアクセス

次のメソッドを使用して、構造化 ARRAYs、構造化 OBJECTs、MAPs の値や要素にアクセスできます。

返される値や要素は VARIANT ではなく、オブジェクトに指定された型です。

次の例では、半構造化 ARRAY の最初の要素と ARRAY(VARCHAR) を SYSTEM$TYPEOF 関数に渡して、その要素のデータ型を返しています。

SELECT
  SYSTEM$TYPEOF(
    ARRAY_CONSTRUCT('San Mateo')[0]
  ) AS semi_structured_array_element,
  SYSTEM$TYPEOF(
    CAST(
      ARRAY_CONSTRUCT('San Mateo') AS ARRAY(VARCHAR)
    )[0]
  ) AS structured_array_element;
Copy
+-------------------------------+-----------------------------+
| SEMI_STRUCTURED_ARRAY_ELEMENT | STRUCTURED_ARRAY_ELEMENT    |
|-------------------------------+-----------------------------|
| VARIANT[LOB]                  | VARCHAR(16777216)[LOB]      |
+-------------------------------+-----------------------------+

次の点に注意してください。

  • 構造化 OBJECT を GET または GET_IGNORE_CASE 関数に渡す場合、キーに定数を指定する必要があります。

    GET 関数に MAP または構造化 ARRAY を渡す場合は、定数を指定する必要はありません。

    また、 MAP を GET_IGNORE_CASE 関数に渡す場合は、定数を指定する必要はありません。

  • 構造化 OBJECT、構造化 ARRAY、または MAP を GET_PATH 関数に渡す場合、パス名に定数を指定する必要があります。

  • 構造化オブジェクトの場合、 OBJECT キーまたは存在しないパスを使用すると、コンパイル時にエラーが発生します。

    これに対して、半構造化オブジェクトに存在しないインデックス、キー、パスを使用すると、関数は NULL を返します。

構造化 ARRAY サイズの決定

構造化 ARRAY サイズを決定するには、 ARRAY を ARRAY_SIZE 関数に渡します。

SELECT ARRAY_SIZE([1,2,3]::ARRAY(NUMBER));
Copy

MAP サイズの決定

MAP のサイズを決定するには、 MAP を MAP_SIZE 関数に渡します。

SELECT MAP_SIZE({'my_key':'my_value'}::MAP(VARCHAR,VARCHAR));
Copy

構造化 ARRAY 内の要素の検索

ある要素が構造化 ARRAY に存在するかどうかを判断するには、 ARRAY_CONTAINS 関数を呼び出します。例:

SELECT ARRAY_CONTAINS(10, [1, 10, 100]::ARRAY(NUMBER));
Copy

構造化 ARRAY 内の要素の位置を決定するには、 ARRAY_POSITION 関数を呼び出します。例:

SELECT ARRAY_POSITION(10, [1, 10, 100]::ARRAY(NUMBER));
Copy

注釈

どちらの関数にも、 ARRAY 型と 比較可能な型 の要素を使用します。

要素の式を VARIANT にキャストしないでください。

MAP がキーを含むかどうかの判断

MAP にキーが含まれているかどうかを判断するには、 MAP_CONTAINS_KEY 関数を呼び出します。

例:

SELECT MAP_CONTAINS_KEY('key_to_find', my_map);
Copy
SELECT MAP_CONTAINS_KEY(10, my_map);
Copy

オブジェクトの比較

次のセクションでは、オブジェクトを比較する方法について説明します。

構造化オブジェクトと半構造化オブジェクトの比較

構造化 ARRAY、構造化 OBJECT、または MAP を、半構造化 ARRAY、 OBJECT、または VARIANT と比較することはできません。

構造化オブジェクトと他の構造化オブジェクトの比較

同じ型の2つのオブジェクト(例えば、2つの構造化 ARRAYs、2つの構造化 OBJECTs、2つの MAPs)を比較することができます。

現在、構造化型を比較するために、次の比較演算子がサポートされています。

  • =

  • !=

  • <

  • <=

  • >=

  • >

2つの構造化オブジェクトを等しいかどうか比較する場合、次の点に注意してください。

  • 一方の型をもう一方の型に 強制 できない場合、比較は失敗します。

  • 数値キーを持つ MAPs を比較する場合、キーは数値として比較されます(VARCHAR の値としては比較されません)。

<<=>=、または > を使用して2つの構造化オブジェクトを比較する場合、構造化オブジェクトフィールドはアルファベット順に比較されます。例えば、次のオブジェクトは:

{'a':2,'b':1}::OBJECT(b INTEGER,a INTEGER)
Copy

次よりも大きいです:

{'a':1,'b':2}::OBJECT(b INTEGER,a INTEGER)
Copy

2つの ARRAYs が重複しているかどうかの判定

2つの構造化 ARRAYs の要素が重複しているかどうかを判断する必要がある場合は、 ARRAYS_OVERLAP 関数を呼び出します。例:

SELECT ARRAYS_OVERLAP(numeric_array, other_numeric_array);
Copy

ARRAYs は 比較可能な型 である必要があります。

この関数に半構造化 ARRAY と構造化 ARRAY を渡すことはできないことに注意してください。どちらの ARRAYs も構造化または半構造化のいずれかである必要があります。

半構造化型の変換

次のセクションでは、構造化 ARRAYs、構造化 OBJECTs、および MAPs を変換する方法を説明します。

半構造化 ARRAYs の変換

これらの関数に構造化 ARRAY を渡すと、関数は同じ型の構造化 ARRAY を返します。

次のセクションでは、これらの関数が構造化 ARRAYs でどのように機能するかを説明します。

配列に要素を追加する関数

次の関数は ARRAY に要素を追加します。

これらの関数の場合、要素の型は ARRAY の型に 強制可能 である必要があります。

例えば、 NUMBER は DOUBLE (ARRAY の型)に強制できるため、次の呼び出しは成功します。

SELECT ARRAY_APPEND( [1,2]::ARRAY(DOUBLE), 3::NUMBER );
Copy

VARCHAR は DOUBLE に強制できるため、次の呼び出しは成功します。

SELECT ARRAY_APPEND( [1,2]::ARRAY(DOUBLE), '3' );
Copy

DATE を NUMBER に強制できないため、次の呼び出しは失敗します。

SELECT ARRAY_APPEND( [1,2]::ARRAY(NUMBER), '2022-02-02'::DATE );
Copy

入力として複数の ARRAYs を受け付ける関数

次の関数は入力引数として複数の ARRAYs を受け付けます。

これらの関数を呼び出す場合、両方の引数が構造化 ARRAYs または半構造化 ARRAYs のどちらか一方である必要があります。例えば、次の呼び出しは、一方の引数が構造化 ARRAY で、もう一方の引数が半構造化 ARRAY であるため、失敗します。

SELECT ARRAY_CAT( [1,2]::ARRAY(NUMBER), ['3','4'] );
Copy
SELECT ARRAY_CAT( [1,2], ['3','4']::ARRAY(VARCHAR) );
Copy

ARRAY_EXCEPT 関数は、第1引数の ARRAY と同じ型の ARRAY を返します。

ARRAY_CAT 関数と ARRAY_INTERSECTION 関数は、両方の入力型に対応できる型の ARRAY を返します。

例えば、次の ARRAY_CAT の呼び出しは、2つの構造化 ARRAYs を返します。

  • 最初の構造化 ARRAY は NULLs を使用できず、0のスケールを持つ NUMBER の値が含まれています。(NUMBER は NUMBER(38, 0) です)。

  • 2番目の構造化 ARRAY には NULL と1のスケールを持つ数字が含まれています。

ARRAY_CAT によって返される ARRAY は NULLs を使用でき、1のスケールで含む NUMBER の値が含まれています。

SELECT
  ARRAY_CAT(
    [1, 2, 3]::ARRAY(NUMBER NOT NULL),
    [5.5, NULL]::ARRAY(NUMBER(2, 1))
  ) AS concatenated_array,
  SYSTEM$TYPEOF(concatenated_array);
Copy
+--------------------+-----------------------------------+
| CONCATENATED_ARRAY | SYSTEM$TYPEOF(CONCATENATED_ARRAY) |
|--------------------+-----------------------------------|
| [                  | ARRAY(NUMBER(38,1))[LOB]          |
|   1,               |                                   |
|   2,               |                                   |
|   3,               |                                   |
|   5.5,             |                                   |
|   undefined        |                                   |
| ]                  |                                   |
+--------------------+-----------------------------------+

ARRAY_CAT 関数の場合、第2引数の ARRAY は第1引数の型に 強制可能 である必要があります。

ARRAY_EXCEPT 関数と ARRAY_INTERSECTION 関数では、第2引数の ARRAY は第1引数の ARRAY に 比較可能 である必要があります。

例えば、 ARRAY(NUMBER) は ARRAY(DOUBLE) と比較可能であるため、次の呼び出しは成功します。

SELECT ARRAY_EXCEPT( [1,2]::ARRAY(NUMBER), [2,3]::ARRAY(DOUBLE) );
Copy

ARRAY(NUMBER) は ARRAY(VARCHAR) と比較可能でないため、次の呼び出しは失敗します。

SELECT ARRAY_EXCEPT( [1,2]::ARRAY(NUMBER), ['2','3']::ARRAY(VARCHAR) );
Copy

半構造化 OBJECTs の変換

以下のセクションでは、別の OBJECT から変換された構造化 OBJECT を返す方法を説明します。

キーと値のペアの順序を変更したり、キーの名前を変更したり、値を指定せずにキーを追加したりする必要がある場合は、 CAST 関数または::演算子 を使用します。詳細については、 ある構造化型から別の構造型へのキャスト をご参照ください。

キーと値のペアの削除

特定のキーと値のペアを削除した既存のオブジェクトのキーと値のペアを含む新しいいオブジェクトを返すには、 OBJECT_DELETE 関数を呼び出します。

この関数を呼び出す際には、次の点に注意してください。

  • キーとなる引数には、定数を指定する必要があります。

  • 指定されたキーが OBJECT 型定義の一部でない場合、呼び出しは失敗します。例えば、次の呼び出しは OBJECT に指定されたキー zip_code が含まれていないため、失敗します。

    SELECT OBJECT_DELETE( {'city':'San Mateo','state':'CA'}::OBJECT(city VARCHAR,state VARCHAR), 'zip_code' );
    
    Copy
    093201 (23001): Function OBJECT_DELETE: expected structured object to contain field zip_code but it did not.
    
  • この関数は構造化 OBJECT を返します。OBJECT の型は削除されたキーを除外します。例えば、 city キーを削除するとします。

    SELECT
      OBJECT_DELETE(
        {'city':'San Mateo','state':'CA'}::OBJECT(city VARCHAR,state VARCHAR),
        'city'
      ) AS new_object,
      SYSTEM$TYPE_OF(new_object);
    
    Copy

    この関数は、 city キーを含まない OBJECT(state VARCHAR) 型の OBJECT を返します。

    +-----------------+--------------------------------------+
    | NEW_OBJECT      | SYSTEM$TYPEOF(NEW_OBJECT)            |
    |-----------------+--------------------------------------|
    | {               | OBJECT(state VARCHAR(16777216))[LOB] |
    |   "state": "CA" |                                      |
    | }               |                                      |
    +-----------------+--------------------------------------+
    
  • この関数がオブジェクトからすべてのキーを削除した場合、 OBJECT() 型の空の構造化 OBJECT を返します。

    SELECT
      OBJECT_DELETE(
        {'state':'CA'}::OBJECT(state VARCHAR),
        'state'
      ) AS new_object,
      SYSTEM$TYPEOF(new_object);
    
    Copy
    +------------+---------------------------+
    | NEW_OBJECT | SYSTEM$TYPEOF(NEW_OBJECT) |
    |------------+---------------------------|
    | {}         | OBJECT()[LOB]             |
    +------------+---------------------------+
    

    構造化 OBJECT の型にキーと値のペアが含まれる場合、それらのペアの名前と型は型の括弧内に含まれます(例えば、 OBJECT(city VARCHAR))。空の構造化 OBJECT はキーと値のペアを含まないため、括弧は空です。

キーと値のペアの挿入と値の更新

既存のオブジェクトのキーと値のペアに、さらにキーと値のペアやキーの新しい値を加えた新しいオブジェクトを返すには、 OBJECT_INSERT 関数を呼び出します。

この関数を呼び出す際には、次の点に注意してください。

  • キーとなる引数には、定数を指定する必要があります。

  • updateFlag 引数が FALSE の場合(新しいキーと値のペアを挿入する場合):

    • OBJECT に既に存在するキーを指定する場合、エラーになります。

      SELECT OBJECT_INSERT(
        {'city':'San Mateo','state':'CA'}::OBJECT(city VARCHAR,state VARCHAR),
        'city',
        'San Jose',
        false
      );
      
      Copy
      093202 (23001): Function OBJECT_INSERT:
        expected structured object to not contain field city but it did.
      
    • この関数は構造化 OBJECT を返します。OBJECT の型には、新しく挿入されたキーが含まれます。例えば、 DOUBLE 値の 94402 を持つ zipcode キーを追加するとします。

      SELECT
        OBJECT_INSERT(
          {'city':'San Mateo','state':'CA'}::OBJECT(city VARCHAR,state VARCHAR),
          'zip_code',
          94402::DOUBLE,
          false
        ) AS new_object,
        SYSTEM$TYPEOF(new_object);
      
      Copy

      この関数は、 OBJECT(city VARCHAR, state VARCHAR, zipcode DOUBLE) 型の OBJECT を返します:

      +-------------------------------------+---------------------------------------------------------------------------------------+
      | NEW_OBJECT                          | SYSTEM$TYPEOF(NEW_OBJECT)                                                             |
      |-------------------------------------+---------------------------------------------------------------------------------------|
      | {                                   | OBJECT(city VARCHAR(16777216), state VARCHAR(16777216), zip_code FLOAT NOT NULL)[LOB] |
      |   "city": "San Mateo",              |                                                                                       |
      |   "state": "CA",                    |                                                                                       |
      |   "zip_code": 9.440200000000000e+04 |                                                                                       |
      | }                                   |                                                                                       |
      +-------------------------------------+---------------------------------------------------------------------------------------+
      

      挿入される値の型は OBJECT 型の定義に追加される型を決定します。この場合、 zipcode の値は DOUBLE にキャストされた値であるため、 zipcode の型は DOUBLE になります。

  • updateFlag 引数が TRUE の場合(既存のキーと値のペアを置き換える場合):

    • OBJECT に存在しないキーを指定する場合、エラーになります。

    • この関数は、同じ型の構造化 OBJECT を返します。

    • 挿入された値の型は、既存のキーの型に 強制 されます。

既存の OBJECT からのキーと値のペアの選択

既存のオブジェクトから選択したキーと値のペアを含む新しいオブジェクトを返すには、 OBJECT_PICK 関数を呼び出します。

この関数を呼び出す際には、次の点に注意してください。

  • キーとなる引数には、定数を指定する必要があります。

  • キーの ARRAY を第2引数として渡すことはできません。各キーを個別の引数として指定する必要があります。

  • この関数は構造化 OBJECT を返します。OBJECT の型には、指定された順序のキーが含まれます。

    例えば、 statecity のキーをこの順序で選択するとします。

    SELECT
      OBJECT_PICK(
        {'city':'San Mateo','state':'CA','zip_code':94402}::OBJECT(city VARCHAR,state VARCHAR,zip_code DOUBLE),
        'state',
        'city') AS new_object,
      SYSTEM$TYPEOF(new_object);
    
    Copy

    この関数は OBJECT(state VARCHAR, city VARCHAR) 型の OBJECT を返します。

    +-----------------------+--------------------------------------------------------------+
    | NEW_OBJECT            | SYSTEM$TYPEOF(NEW_OBJECT)                                    |
    |-----------------------+--------------------------------------------------------------|
    | {                     | OBJECT(state VARCHAR(16777216), city VARCHAR(16777216))[LOB] |
    |   "state": "CA",      |                                                              |
    |   "city": "San Mateo" |                                                              |
    | }                     |                                                              |
    +-----------------------+--------------------------------------------------------------+
    

MAPs の変換

MAPs を変換するには、次の関数を使用します。

構造化型の操作

次のセクションでは、構造化型のオブジェクトで、さまざまな SQL 関数とセット演算子を使用する方法について説明します。

構造化型での FLATTEN 関数の使用

構造化 ARRAYs、構造化 OBJECTs、 MAPs を FLATTEN 関数に渡すことができます。半構造化データ型の場合と同様に、PATH 引数を使用してフラット化される値を指定することができます。

  • フラット化される値が構造化 ARRAY で RECURSIVE 引数が FALSE の場合、 value 列には ARRAY と同じ型の値が含まれます。

    例:

    SELECT value, SYSTEM$TYPEOF(value)
      FROM TABLE(FLATTEN(INPUT => [1.08, 2.13, 3.14]::ARRAY(DOUBLE)));
    
    Copy
    +-------+----------------------+
    | VALUE | SYSTEM$TYPEOF(VALUE) |
    |-------+----------------------|
    |  1.08 | FLOAT[DOUBLE]        |
    |  2.13 | FLOAT[DOUBLE]        |
    |  3.14 | FLOAT[DOUBLE]        |
    +-------+----------------------+
    
  • フラット化される値が MAP で、 RECURSIVE 引数が FALSE の場合、 key 列には MAP キーと同じ型のキーが含まれ、 value 列には MAP 値と同じ型の値が含まれます。

    例:

    SELECT key, SYSTEM$TYPEOF(key), value, SYSTEM$TYPEOF(value)
      FROM TABLE(FLATTEN(INPUT => {'my_key': 'my_value'}::MAP(VARCHAR, VARCHAR)));
    
    Copy
    +--------+------------------------+----------+------------------------+
    | KEY    | SYSTEM$TYPEOF(KEY)     | VALUE    | SYSTEM$TYPEOF(VALUE)   |
    |--------+------------------------+----------+------------------------|
    | my_key | VARCHAR(16777216)[LOB] | my_value | VARCHAR(16777216)[LOB] |
    +--------+------------------------+----------+------------------------+
    
  • それ以外の場合、 keyvalue の列は VARIANT 型になります。

MAPs の場合、返されるキーと値の順序は不確定です。

PARSE_JSON 関数の使用

PARSE_JSON 関数は構造化型を返さないことに注意してください。

集合演算子と CASE 式での構造化型の使用

構造化 ARRAYs、構造化 OBJECTs、MAPs は次で使用することができます。

集合演算子の場合、異なる型が異なる式で使用されている場合(例えば、一方の型が ARRAY(NUMBER) で、もう一方が ARRAY(DOUBLE) の場合)、一方の型はもう一方の型に 強制 されます。

他の半構造化関数の操作

次の関数は、構造化 ARRAY、構造化 OBJECT、または MAP を入力引数として受け付けません。

構造化型を入力として渡すとエラーになります。

ドライバーを使用したアプリケーションでの構造化型へのアクセス

ドライバーを使用するアプリケーション(ODBC または JDBC ドライバー、Python用Snowflakeコネクタなど)では、構造化型の値は半構造化型として返されます。例:

  • 構造化 ARRAY 列は、半構造化 ARRAY としてクライアントアプリケーションに返されます。

  • 構造化 OBJECT または MAP 列は、半構造化 OBJECT としてクライアントアプリケーションに返されます。

ユーザー定義関数(UDFs)とストアドプロシージャでの構造化型の使用

ユーザー定義関数(UDF)、ユーザー定義テーブル関数(UDTF)、またはストアドプロシージャを SQL または Snowflakeスクリプト で作成する場合、引数と戻り値に構造化型を使用できます。例:

CREATE OR REPLACE FUNCTION my_udf(
    location OBJECT(city VARCHAR, zipcode NUMBER, val ARRAY(BOOLEAN)))
  RETURNS VARCHAR
  AS
  $$
    ...
  $$;
Copy
CREATE OR REPLACE FUNCTION my_udtf(check BOOLEAN)
  RETURNS TABLE(col1 ARRAY(VARCHAR))
  AS
  $$
  ...
  $$;
Copy
CREATE OR REPLACE PROCEDURE my_procedure(values ARRAY(INTEGER))
  RETURNS ARRAY(INTEGER)
  LANGUAGE SQL
  AS
  $$
    ...
  $$;
Copy

注釈

構造化型は、他の言語(Java、 JavaScript、Python、Scala)での UDFs、 UDTFs、ストアドプロシージャではまだサポートされていません。

構造化型に関する情報の表示

次のセクションでは、構造化型に関する情報を表示するために使用できるビューとコマンドについて説明します。

SHOW COLUMNS コマンドを使用した構造化型情報の表示

SHOW COLUMNS コマンドの出力では、 data_type 列に要素、キー、値の型に関する情報が含まれます。

DESCRIBE とその他の SHOW コマンドを使用した構造化型情報の表示

次のコマンドの出力には、構造化型に関する情報が含まれます。

例えば、 DESCRIBE RESULT 出力では、 MAP(VARCHAR, VARCHAR) 列の行には type 列に次の値が含まれます。

map(VARCHAR(16777216), VARCHAR(16777216))
Copy

ARRAY(NUMBER) 列の行には、 type 列に次の値が含まれます。

ARRAY(NUMBER(38,0))
Copy

データベースで使用される構造化型に関する情報の表示

構造化型の列の場合、 INFORMATION_SCHEMA COLUMNS ビュー は列の基本データ型(ARRAY、 OBJECT、または MAP)に関する情報のみを提供します。

例えば、 data_type 列には「ARRAY」、「OBJECT」、または「MAP」のみが含まれます。列には、要素、キー、値の型は含まれません。

要素、キー、値の型に関する情報を表示するには、次のビューを使用します。