

 Amazon Redshift は、パッチ 198 以降、新しい Python UDF の作成をサポートしなくなります。既存の Python UDF は、2026 年 6 月 30 日まで引き続き機能します。詳細については、[ブログ記事](https://aws.amazon.com/blogs/big-data/amazon-redshift-python-user-defined-functions-will-reach-end-of-support-after-june-30-2026/)を参照してください。

# 半構造化データのクエリ
<a name="query-super"></a>

Amazon Redshift を使用すると、JSON、Avro、Ion などの半構造化データを構造化データとともにクエリおよび分析できます。半構造化データとは、階層構造またはネスト構造を可能にする柔軟なスキーマを持つデータを指します。以下のセクションでは、Amazon Redshift のオープンデータ形式のサポートを使用して半構造化データをクエリする方法について説明します。これにより、複雑なデータ構造から有益な情報を引き出すことができます。

Amazon Redshift は PartiQL 言語を使用して、リレーショナルデータ、半構造化データ、ネストされたデータへの SQL 互換アクセスを提供します。

PartiQL は、動的型で動作します。このアプローチにより、構造化、半構造化、およびネストされたデータセットの組み合わせに対して、直感的なフィルタリングや結合、および集約を行えるようになります。PartiQL 構文では、ネストされたデータにアクセスするときに、パスナビゲーションにドット付き表記と配列添字を使用します。また、FROM 句の項目が配列を反復処理し、不正なオペレーションに使用できるようにします。以下では、パスおよび配列のナビゲーション、ネスト解除、または結合を、SUPER データ型で行う場合の、さまざまなクエリパターンについて説明します。PartiQL の詳細については、「[PartiQL – Amazon Redshift用の SQL 互換クエリ言語](super-partiql.md)」を参照してください。

## ナビゲーション
<a name="navigation"></a>

Amazon Redshift は PartiQL を使用して、それぞれ [...] 角括弧とドット表記を使用して、配列と構造体へのナビゲーションを可能にします。さらに、ドット表記を使用して構造体に、角括弧表記を使用して配列にナビゲーションを混在させることができます。例えば、次のステートメントでは、SUPER オブジェクトの 1 レベル深くネストされた配列の 3 番目の要素のみを選択します。

```
SELECT super_object.array[2];
         
 array
---------------
 third_element
```

フィルタリング、結合、集計などのデータ操作を実行するときは、ドットと角括弧の表記を使用できます。これらの表記は、通常列参照を含んでいるクエリ内の任意の場所で使用できます。例えば、次のステートメントでは、タイプ `UPDATED` のイベントの数を選択します。

```
SELECT COUNT(*)
FROM test_json
WHERE all_data.data.pnr.events[0]."eventType" = 'UPDATED';
         
 eventType | count
-----------+-------
 "UPDATED" | 1
```

PartiQL ナビゲーションの詳細な例については、「[Amazon Redshift で半構造化データを使用する例](super-examples.md)」を参照してください。

## ネストされていないクエリ
<a name="unnest"></a>

クエリのネストを解除するために、Amazon Redshift には、SUPER 配列を反復処理する 2 つの方法があります。FROM 句の PartiQL 構文と UNNEST オペレーションです。どちらのネスト解除メソッドも同じ出力になります。UNNEST オペレーションについては、「[FROM 句](r_FROM_clause30.md)」を参照してください。UNNEST オペレーションの使用例については、「[UNNEST の例](r_FROM_clause-unnest-examples.md)」を参照してください。

Amazon Redshift は、クエリの FROM 句で PartiQL 構文を使用して SUPER 配列をナビゲートできます。前の例を使用して、次の例では、属性値 `c_orders` を繰り返し処理しています。

```
SELECT orders.*, o FROM customer_orders orders, orders.c_orders o;
```

 FROM 句項目 `x (AS) y` を使用してネスト解除する PartiQL 構文では、`y` が(SUPER) 配列式 x 内の各 (SUPER) 値を反復処理することを意味します。この場合、`x` は SUPER 表現であり、`y` は `x` のエイリアスです。

左のオペランドは、通常のナビゲーションのためにドットと角括弧の表記を使用することもできます。次の例では、`customer_orders_lineitem c` は `customer_order_lineitem` ベースのテーブルに対する反復処理であり、`c.c_orders o` は `c.c_orders` 配列に対する反復処理です。配列内の配列である `o_lineitems` 属性を反復処理するには、次のように複数の句を追加できます。

```
SELECT c.*, o, l FROM customer_orders_lineitem c, c.c_orders o, o.o_lineitems l;
```

Amazon Redshift では、AT キーワードを使用して配列の反復処理を行う際の、配列インデックスもサポートしています。句 `x AS y AT z` は、配列 `x` を反復処理し、配列インデックスとしてフィールド `z,` を生成します。次の例は、配列インデックスがどのように機能するかを示しています。

```
SELECT c_name,
       orders.o_orderkey AS orderkey,
       index AS orderkey_index
FROM customer_orders_lineitem c, c.c_orders AS orders AT index 
ORDER BY orderkey_index;

c_name             | orderkey | orderkey_index
-------------------+----------+----------------
Customer#000008251 | 3020007  |        0
Customer#000009452 | 4043971  |        0
  (2 rows)
```

次の例は、スカラー配列を反復処理する例です。

```
CREATE TABLE bar AS SELECT json_parse('{"scalar_array": [1, 2.3, 45000000]}') AS data;

SELECT element, index FROM bar AS b, b.data.scalar_array AS element AT index;

 index | element
-------+----------
     0 | 1
     1 | 2.3
     2 | 45000000
(3 rows)
```

次の例では、複数のレベルの配列を繰り返し処理します。この例では、複数の UNNEST 句を使用して、最も内側の配列を反復処理します。`f.multi_level_array` AS 配列は `multi_level_array` を反復処理します。配列 AS 要素は、`multi_level_array` 内の配列に対する反復処理を表します。

```
CREATE TABLE foo AS SELECT json_parse('[[1.1, 1.2], [2.1, 2.2], [3.1, 3.2]]') AS multi_level_array;

SELECT array, element FROM foo AS f, f.multi_level_array AS array, array AS element;

 element | array
---------+---------
 1.1     | [1.1,1.2]
 1.2     | [1.1,1.2]
 2.1     | [2.1,2.2] 
 2.2     | [2.1,2.2]
 3.1     | [3.1,3.2] 
 3.2     | [3.1,3.2] 
(6 rows)
```

FROM 句の詳細については、「[FROM 句](r_FROM_clause30.md)」を参照してください。SUPER クエリをネスト解除するその他の例については、「[Amazon Redshift で半構造化データを使用する例](super-examples.md)」を参照してください。

## オブジェクトのピボット解除
<a name="unpivoting"></a>

オブジェクトのピボット解除を実行する際、Amazon Redshift は、PartiQL 構文により SUPER オブジェクトを反復処理します。この処理は、UNPIVOT キーワードを指定しながらクエリの FROM 句を使用することで実現されます。次の例では、式は `c.c_orders[0]` オブジェクトです。このクエリ例では、オブジェクトから返された各属性を反復処理します。

```
SELECT attr as attribute_name, json_typeof(val) as value_type 
FROM customer_orders_lineitem c, UNPIVOT c.c_orders[0] AS val AT attr 
WHERE c_custkey = 9451;

 attribute_name  | value_type
-----------------+------------
 o_orderstatus   | string
 o_clerk         | string
 o_lineitems     | array
 o_orderdate     | string
 o_shippriority  | number
 o_totalprice    | number
 o_orderkey      | number
 o_comment       | string
 o_orderpriority | string
(9 rows)
```

ネスト解除構文と同様に、ピボット解除構文も FROM 句の拡張の 1 つです。違いは、ピボット解除構文では UNPIVOT キーワードを使用して、配列ではなくオブジェクトを反復処理することを示す点です。これは、AS `value_alias` を使用してオブジェクト内のすべての値を反復処理し、AT `attribute_alias` を使用してすべての属性を反復処理します。次の構文を検討してください。

```
UNPIVOT expression AS value_alias [ AT attribute_alias ]
```

Amazon Redshift は、次のように、単一の FROM 句でオブジェクトのピボット解除と配列のネスト解除の使用をサポートしています。

```
SELECT attr as attribute_name, val as object_value
FROM customer_orders_lineitem c, c.c_orders AS o, UNPIVOT o AS val AT attr 
WHERE c_custkey = 9451;
```

オブジェクトのピボット解除を使用する場合、Amazon Redshift では相関ピボット解除はサポートされません。具体的には、異なるクエリレベルで複数のピボット解除が存在し、内側のピボット解除が外側のピボット解除を参照している場合が考えられます。Amazon Redshift は、このタイプの複数にわたるピボット解除をサポートしていません。

FROM 句の詳細については、「[FROM 句](r_FROM_clause30.md)」を参照してください。SUPER タイプでピボットを使用する例については、「[Amazon Redshift で半構造化データを使用する例](super-examples.md)」を参照してください。

## 動的型付け
<a name="dynamic-typing-lax-processing"></a>

動的型付けでは、ドットと角括弧のパスから抽出されたデータを明示的にキャストする必要はありません。Amazon Redshift では、動的型付けを使用して、クエリで使用する前にデータ型を宣言することなく、スキーマレスの SUPER データを処理します。動的型付けでは、明示的に Amazon Redshift 型にキャストすることなく、SUPER データ列に移動した結果が使用されます。動的型付けは、結合および GROUP BY 句で最も便利です。次の例では、通常の Amazon Redshift 型にドット式と角括弧式を明示的にキャストする必要がない SELECT ステートメントを使用しています。タイプの互換性および変換の詳細については、「[型の互換性と変換](c_Supported_data_types.md#r_Type_conversion)」を参照してください。

注文のステータスが `shipped` である行を検索する次の例を考えてみます。

```
SELECT c_orders[0].o_orderkey
FROM customer_orders_lineitem
WHERE c_orders[0].o_orderstatus = 'shipped';
```

c\$1orders[0].o\$1orderstatus の値が文字列「shipped」の場合、この例のクエリの等号は `true` と評価されます。他のすべての場合、等号は `false` と評価されます。これには、等号の引数が異なるタイプである場合も含まれます。例えば、注文のステータスが整数の場合、その行は選択されません。

### 動的型と静的型
<a name="dynamic-typing-lax-processing-dynamic-and-static"></a>

動的型付けを使用しないと、c\$1orders[0].o\$1orderstatus が文字列、整数、または構造体のいずれであるかを判断できません。c\$1orders[0].o\$1orderstatus が SUPER データ型であると判断できるのは、Amazon Redshift スカラー、配列、または構造体の場合のみです。c\$1orders[0].o\$1orderstatus の静的型は、SUPER データ型です。従来、型は SQL では暗黙的に静的型です。

Amazon Redshift は、スキーマレスデータの処理に動的型付けを使用します。クエリがデータを評価すると、c\$1orders[0].o\$1orderstatus は特定のタイプであることが判明します。例えば、customer\$1orders\$1lineitem の最初のレコードで c\$1orders[0].o\$1orderstatus を評価すると、整数になることがあります。2 番目のレコードを評価すると、文字列になることがあります。これらは、式の動的型です。

動的型を持つドット式と角括弧式で SQL 演算子または関数を使用すると、Amazon Redshift は、それぞれの静的型で標準の SQL 演算子または関数を使用する場合と同様の結果を生成します。この例では、パス式の動的型が文字列である場合、文字列 'P' との比較は意味を持ちます。c\$1orders[0].o\$1orderstatus の動的型が文字列以外のデータ型であるときはいつでも、等式が false を返します。誤って入力された引数が使用されると、他の関数は null を返します。

次の例では、静的型付けを使用して前のクエリを書き込みます。

```
SELECT c_custkey
FROM customer_orders_lineitem
WHERE CASE WHEN JSON_TYPEOF(c_orders[0].o_orderstatus) = 'string'
           THEN c_orders[0].o_orderstatus::VARCHAR = 'P'
           ELSE FALSE END;
```

等価述語と比較述語の次の違いに注意してください。前の例では、等価述語を下回る述語に置き換えると、セマンティクスは false ではなく null を生成します。

```
SELECT c_orders[0]. o_orderkey
FROM customer_orders_lineitem
WHERE c_orders[0].o_orderstatus <= 'P';
```

この例では、c\$1orders[0].o\$1orderstatus が文字列の場合、アルファベット順で「P」以下であれば、Amazon Redshift は true を返します。アルファベット順で 'P' より大きい場合、Amazon Redshift は false を返します。ただし、c\$1orders[0].o\$1orderstatus が文字列でない場合、Amazon Redshift では次のクエリに示すように、異なるタイプの値を比較できないため、Amazon Redshift は null を返します。

```
SELECT c_custkey
FROM customer_orders_lineitem
WHERE CASE WHEN JSON_TYPEOF(c_orders[0].o_orderstatus) = 'string'
           THEN c_orders[0].o_orderstatus::VARCHAR <= 'P'
           ELSE NULL END;
```

動的型付けは、最小限の比較を行える型の比較から除外されません。例えば、CHAR と VARCHAR の両方の Amazon Redshift スカラー型を SUPER に変換できます。これらは、Amazon Redshift CHAR および VARCHAR 型に似た末尾の空白文字を無視するなど、文字列と同等です。同様に、整数型、小数型、および浮動小数点値は SUPER 値と同等です。特に 10 進数列の場合、各値は異なるスケールを持つこともできます。Amazon Redshift では、これらを引き続き動的型と見なします。

また、Amazon Redshift は、オブジェクトや配列の深さを評価し、すべての属性を比較するなど、深さが等しいと評価されるオブジェクトや配列の等価性もサポートしています。deep equal を実行するプロセスは時間がかかる可能性があるため、deep equal の使用には注意が必要です。

### 結合での動的型付けの使用
<a name="dynamic-typing-lax-processing-joins"></a>

結合の場合、動的型付けは、長い CASE WHEN 分析を実行して表示される可能性のあるデータ型を見つける代わりに、値をさまざまな動的型と自動的に一致させます。例えば、組織がパートキーに使用していた形式を時間の経過とともに変更したと仮定します。

発行された最初の整数部分キーは、'A55' などの文字列部分キーに置き換えられ、後で文字列と数字を組み合わせた ['X', 10] などの配列部分キーに再び置き換えられます。Amazon Redshift では、パートキーについて長いケース分析を行う必要がなく、次の例に示すように、結合を使用できます。

```
SELECT c.c_name
    ,l.l_extendedprice
    ,l.l_discount
FROM customer_orders_lineitem c
    ,c.c_orders o
    ,o.o_lineitems l
    ,supplier_partsupp s
    ,s.s_partsupps ps
WHERE l.l_partkey = ps.ps_partkey
AND c.c_nationkey = s.s_nationkey
ORDER BY c.c_name;
```

次の例では、動的型付けを使用しない場合、同じクエリがどれほど複雑で非効率的であるかを示しています。

```
SELECT c.c_name
    ,l.l_extendedprice
    ,l.l_discount
FROM customer_orders_lineitem c
    ,c.c_orders o
    ,o.o_lineitems l
    ,supplier_partsupp s
    ,s.s_partsupps ps
WHERE CASE WHEN IS_INTEGER(l.l_partkey) AND IS_INTEGER(ps.ps_partkey)
           THEN l.l_partkey::integer = ps.ps_partkey::integer
           WHEN IS_VARCHAR(l.l_partkey) AND IS_VARCHAR(ps.ps_partkey)
           THEN l.l_partkey::varchar = ps.ps_partkey::varchar
           WHEN IS_ARRAY(l.l_partkey) AND IS_ARRAY(ps.ps_partkey)
                AND IS_VARCHAR(l.l_partkey[0]) AND IS_VARCHAR(ps.ps_partkey[0])
                AND IS_INTEGER(l.l_partkey[1]) AND IS_INTEGER(ps.ps_partkey[1])
           THEN l.l_partkey[0]::varchar = ps.ps_partkey[0]::varchar
                AND l.l_partkey[1]::integer = ps.ps_partkey[1]::integer
           ELSE FALSE END
AND c.c_nationkey = s.s_nationkey
ORDER BY c.c_name;
```

## 大文字と小文字を区別しないクエリ
<a name="case-insensitive-super-queries"></a>

COLLATE 関数を使用するか、列またはデータベースレベルで照合を設定することで、SUPER データに対して大文字と小文字を区別しない文字列比較を実行できます。テーブル作成時の照合設定の詳細については、「[CREATE TABLE](r_CREATE_TABLE_NEW.md)」を参照してください。SUPER データ演算子および関数との照合動作については、「[照合動作](operators-functions.md#collation-behavior)」を参照してください。

次の例では、SUPER データから抽出された文字列値に対して COLLATE 関数を使用しています。

```
CREATE TABLE events (data SUPER);
INSERT INTO events VALUES (JSON_PARSE('{"status": "Active", "name": "Event1"}'));
INSERT INTO events VALUES (JSON_PARSE('{"status": "ACTIVE", "name": "Event2"}'));
INSERT INTO events VALUES (JSON_PARSE('{"status": "active", "name": "Event3"}'));

SELECT data.name FROM events 
WHERE COLLATE(data.status::VARCHAR, 'case_insensitive') = 'active';

 name
----------
 "Event1"
 "Event2"
 "Event3"
(3 rows)
```

テーブルの作成時に大文字と小文字を区別しない照合を使用して SUPER 列を定義することもできます。この場合、列のすべての文字列比較では大文字と小文字が区別されません。

```
CREATE TABLE events_ci (data SUPER COLLATE CASE_INSENSITIVE);
INSERT INTO events_ci VALUES (JSON_PARSE('{"status": "Active"}'));
INSERT INTO events_ci VALUES (JSON_PARSE('{"status": "ACTIVE"}'));

SELECT * FROM events_ci WHERE data.status::VARCHAR = 'active';

 data
-----------------------
 {"status":"Active"}
 {"status":"ACTIVE"}
(2 rows)
```

## Lax のセマンティクス
<a name="lax-semantics"></a>

デフォルトでは、SUPER 値に対するナビゲーションオペレーションは、ナビゲーションが無効であるときにエラーを返す代わりに null を返します。SUPER 値がオブジェクトでない場合、または SUPER 値がオブジェクトであるが、クエリで使用される属性名が含まれていない場合、オブジェクトのナビゲーションは無効です。例えば、次のクエリは、SUPER データ列の cdata で無効な属性名にアクセスします。

```
SELECT c.c_orders.something FROM customer_orders_lineitem c;
```

SUPER 値が配列でない場合、または配列インデックスが範囲外の場合、配列ナビゲーションは null を返します。次のクエリは、c\$1orders[1][1] が範囲外であるため、null を返します。

```
SELECT c.c_orders[1][1] FROM customer_orders_lineitem c;
```

Lax セマンティクスは、動的型付けを使用して SUPER 値をキャストする場合に特に便利です。SUPER 値を間違ったタイプにキャストすると、キャストが無効な場合、エラーではなく null が返されます。例えば、次のクエリは、オブジェクト属性 o\$1orderstatus の文字列値 'Good' を INTEGER にキャストできないため、null を返します。Amazon Redshift は、VARCHAR から INTEGER へのキャストではエラーを返しますが、SUPER キャストではエラーを返しません。

```
SELECT c.c_orders.o_orderstatus::integer FROM customer_orders_lineitem c;
```

## 順
<a name="order-by"></a>

Amazon Redshift では、動的型が異なる値間の SUPER 比較を定義していません。文字列である SUPER 値は、数値である SUPER 値より小さくも大きくもありません。SUPER 列で ORDER BY 句を使用するために、Amazon Redshift では、ORDER BY 句を使用して SUPER 値をランク付けするときに観察されるさまざまなタイプ間の全順序を定義します。動的型間の順序は、ブール値、数値、文字列、配列、オブジェクトです。

SUPER クエリで GROUP BY と ORDER BY を使用する例については、「[半構造化データのフィルタリング](super-examples.md#super-examples-filter)」を参照してください。