

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 查詢巢狀資料
<a name="query-nested-data"></a>

AWS Clean Rooms 提供關聯式和巢狀資料的 SQL 相容存取。

AWS Clean Rooms 存取巢狀資料時， 會使用虛線符號和陣列下標進行路徑導覽。它還允許FROM子句項目在陣列上反覆運算，並用於不巢狀操作。下列主題提供不同查詢模式的描述，這些查詢模式將array/struct/map資料類型的使用與路徑和陣列導覽、取消巢狀和聯結結合結合。

**Topics**
+ [Navigation (導覽)](#navigation)
+ [解除巢狀化查詢](#unnesting-queries)
+ [寬鬆的語義](#lax-semantics)
+ [自我檢查的種類](#types-of-introspection)

## Navigation (導覽)
<a name="navigation"></a>

AWS Clean Rooms 可分別使用`[...]`括號和點符號來導覽陣列和結構。此外，您也可以使用點符號將導覽混合到結構中，以及使用括號符號將導覽混合到陣列中。

**Example**  
例如，下列範例查詢假設`c_orders`陣列資料欄是具有 結構的陣列，而 屬性名為 `o_orderkey`。  

```
SELECT cust.c_orders[0].o_orderkey FROM customer_orders_lineitem AS cust;
```

您可以在所有類型的查詢中使用點和括號符號，例如篩選、聯結和彙總。您可以在查詢中使用這些符號，其中通常有欄參考。

**Example**  
下列範例會使用篩選結果的 SELECT 陳述式。  

```
SELECT count(*) FROM customer_orders_lineitem WHERE c_orders[0].o_orderkey IS NOT NULL;
```

**Example**  
下列範例會在 GROUP BY 和 ORDER BY 子句中使用括號和點導覽。  

```
SELECT c_orders[0].o_orderdate,
       c_orders[0].o_orderstatus,
       count(*)
FROM customer_orders_lineitem
WHERE c_orders[0].o_orderkey IS NOT NULL
GROUP BY c_orders[0].o_orderstatus,
         c_orders[0].o_orderdate
ORDER BY c_orders[0].o_orderdate;
```

## 解除巢狀化查詢
<a name="unnesting-queries"></a>

若要巢狀查詢， AWS Clean Rooms 請啟用陣列的反覆運算。它透過使用查詢的 FROM 子句導覽陣列來實現此目的。

**Example**  
使用上一個範例，下列範例會迭代 `c_orders` 的屬性值。  

```
SELECT o FROM customer_orders_lineitem c, c.c_orders o;
```

解除巢狀化語法是 FROM 子句的擴充功能。在標準 SQL 中，FROM 子句 `x (AS) y` 代表 `y` 迭代關係 `x` 的每個元組。在這種情況下，`x` 指的是關係，而 `y` 指的是關係 `x` 的別名。同樣地，使用 FROM 子句項目取消巢狀的語法`x (AS) y`表示`y`反覆運算陣列表達式 中的每個值`x`。在此情況下， `x` 是陣列表達式，`y`也是 的別名`x`。

左運算元也可以使用點和括號符號進行常規導覽。

**Example**  
在上一個範例中：  
+ `customer_orders_lineitem c` 是`customer_order_lineitem`基礎資料表上的反覆運算
+ `c.c_orders o` 是對 的反覆運算 `c.c_orders array`
若要迭代 `o_lineitems` 屬性 (即陣列中的陣列)，您可以新增多個子句。



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

AWS Clean Rooms 也支援使用 AT關鍵字在陣列上反覆運算的陣列索引。子句會反覆`x AS y AT z`運算陣列，`x`並產生欄位 `z`，也就是陣列索引。

**Example**  
下列範例顯示陣列索引的運作方式。  

```
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)
```

**Example**  
下列範例會迭代純量陣列。  

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

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

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

**Example**  
下列範例會迭代多個層級的陣列。這個範例會使用多個解除巢狀化子句來迭代到最內層的陣列。`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;

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

## 寬鬆的語義
<a name="lax-semantics"></a>

根據預設，巢狀資料值的導覽操作會傳回 null，而不是在導覽無效時傳回錯誤。如果巢狀資料值不是物件，或者巢狀資料值是物件，但不包含查詢中使用的屬性名稱，則物件導覽會無效。

**Example**  
例如，下列查詢會存取巢狀資料欄 中的無效屬性名稱`c_orders`：  

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

如果巢狀資料值不是陣列或陣列索引超出範圍，則陣列導覽會傳回 null。

**Example**  
下列查詢傳回 null`c_orders[1][1]`，因為 超出範圍。  

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

## 自我檢查的種類
<a name="types-of-introspection"></a>

巢狀資料類型資料欄支援檢查函數，可傳回 類型和有關 值的其他類型資訊。AWS Clean Rooms 支援下列布林值函數的巢狀資料欄：
+ DECIMAL\$1PRECISION
+ DECIMAL\$1SCALE
+ IS\$1ARRAY 
+ IS\$1BIGINT 
+ IS\$1CHAR 
+ IS\$1DECIMAL 
+ IS\$1FLOAT 
+ IS\$1INTEGER 
+ IS\$1OBJECT 
+ IS\$1SCALAR 
+ IS\$1SMALLINT 
+ IS\$1VARCHAR 
+ JSON\$1TYPEOF 

如果輸入值為 null，所有這些函數傳回 false。IS\$1SCALAR、IS\$1OBJECT 和 IS\$1ARRAY 是互斥的，涵蓋除 null 之外的所有可能值。若要推斷與資料對應的類型， AWS Clean Rooms 會使用 JSON\$1TYPEOF 函數，傳回巢狀資料值的類型 （最上層），如下列範例所示：

```
SELECT JSON_TYPEOF(r_nations) FROM region_nations;
 json_typeof
 ------------- 
array
(1 row)
```

```
SELECT JSON_TYPEOF(r_nations[0].n_nationkey) FROM region_nations;
 json_typeof
 -------------
 number
```