選取您的 Cookie 偏好設定

我們使用提供自身網站和服務所需的基本 Cookie 和類似工具。我們使用效能 Cookie 收集匿名統計資料,以便了解客戶如何使用我們的網站並進行改進。基本 Cookie 無法停用,但可以按一下「自訂」或「拒絕」以拒絕效能 Cookie。

如果您同意,AWS 與經核准的第三方也會使用 Cookie 提供實用的網站功能、記住您的偏好設定,並顯示相關內容,包括相關廣告。若要接受或拒絕所有非必要 Cookie,請按一下「接受」或「拒絕」。若要進行更詳細的選擇,請按一下「自訂」。

教學課程:使用 Amazon Redshift Spectrum 查詢巢狀資料 - Amazon Redshift

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

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

教學課程:使用 Amazon Redshift Spectrum 查詢巢狀資料

本教學課程示範如何使用 Redshift Spectrum 查詢巢狀資料。巢狀資料是包含巢狀欄位的資料。巢狀欄位是做為單一實體聯結在一起的欄位,例如陣列、結構或物件。

概觀

Amazon Redshift Spectrum 支援查詢 Parquet、ORC、JSON 和 Ion 檔案格式的巢狀資料。Redshift Spectrum 會存取使用外部資料表的資料。您可以建立使用複雜資料類型 structarraymap 的外部資料表。

例如,假設您的資料檔案在 Amazon S3 名為 customers 的資料夾中包含下列資料。雖然沒有單一根元素,此取樣資料中的每個 JSON 物件代表資料表中的資料列。

{"id": 1, "name": {"given": "John", "family": "Smith"}, "phones": ["123-457789"], "orders": [{"shipdate": "2018-03-01T11:59:59.000Z", "price": 100.50}, {"shipdate": "2018-03-01T09:10:00.000Z", "price": 99.12}] } {"id": 2, "name": {"given": "Jenny", "family": "Doe"}, "phones": ["858-8675309", "415-9876543"], "orders": [] } {"id": 3, "name": {"given": "Andy", "family": "Jones"}, "phones": [], "orders": [{"shipdate": "2018-03-02T08:02:15.000Z", "price": 13.50}] }

您現在可以使用 Amazon Redshift Spectrum 來查詢檔案中的巢狀資料。下列教學課程說明如何使用 Apache Parquet 資料執行此操作。

先決條件

如果您尚未使用 Redshift Spectrum,請先遵循開始使用 Amazon Redshift Spectrum中的步驟,再繼續進行。

如要建立外部結構描述,請將以下命令中的 IAM 角色 ARN 替換為您在建立 IAM 角色中建立的角色 ARN。然後,在您的 SQL 用戶端中執行命令。

create external schema spectrum from data catalog database 'myspectrum_db' iam_role 'arn:aws:iam::123456789012:role/myspectrum_role' create external database if not exists;

步驟 1:建立包含巢狀資料的外部資料表

您可以從 Amazon S3 下載來源資料以檢視來源資料。

若要建立此教學課程的外部資料表,請執行以下命令。

CREATE EXTERNAL TABLE spectrum.customers ( id int, name struct<given:varchar(20), family:varchar(20)>, phones array<varchar(20)>, orders array<struct<shipdate:timestamp, price:double precision>> ) STORED AS PARQUET LOCATION 's3://redshift-downloads/tickit/spectrum/customers/';

在上述範例中,外部資料表 spectrum.customers 使用 structarray 資料類型來定義具有巢狀資料的資料欄。Amazon Redshift Spectrum 支援查詢 Parquet、ORC、JSON 和 Ion 檔案格式的巢狀資料。Apache Parquet 檔案的 STORED AS 參數是 PARQUETLOCATION 參數必須參考包含巢狀資料或檔案的 Amazon S3 資料夾。如需詳細資訊,請參閱CREATE EXTERNAL TABLE

您可以在任何層級將 arraystruct 類型形成巢狀。例如,您可以如以下範例所示定義名為 toparray 的資料欄。

toparray array<struct<nestedarray: array<struct<morenestedarray: array<string>>>>>

您也可以如以下範例中的資料欄 x 所示,將 struct 類型形成巢狀。

x struct<a: string, b: struct<c: integer, d: struct<e: string> > >

步驟 2:在 Amazon S3 中使用 SQL 延伸模組查詢您的巢狀資料

Redshift Spectrum 支援透過 Amazon Redshift SQL 語法的延組模組查詢 arraymapstruct 複雜類型。

延組模組 1:存取 structs 的欄位

您可以使用可將欄位名稱串連為路徑的點表示法,從 struct 資料欄擷取資料。例如,以下查詢會傳回客戶的名字和姓氏。名字是透過長路徑 c.name.given 存取。姓氏是透過長路徑 c.name.family 存取。

SELECT c.id, c.name.given, c.name.family FROM spectrum.customers c;

前述查詢會傳回下列資料。

id | given | family ---|-------|------- 1 | John | Smith 2 | Jenny | Doe 3 | Andy | Jones (3 rows)

struct 可以是另一個 struct 的資料欄,可以是任何層級的另一個 struct 的資料欄。存取這類深入巢狀 struct 中資料欄的路徑可以有任意長度。例如,查看以下範例中資料欄 x 的定義。

x struct<a: string, b: struct<c: integer, d: struct<e: string> > >

您可以以 x.b.d.e 的形式存取 e 中的資料。

延伸模組 2:在 FROM 子句中存取 array 的範圍

您可以從 array 資料欄擷取資料 (並且透過延伸模組 map 資料欄),方法是在 FROM 子句中指定 array 資料欄以取代資料表名稱。延伸模組會套用到主查詢的 FROM 子句,以及子查詢的 FROM 子句。

您可以依位置參考 array 元素,例如 c.orders[0]。(預覽)

藉由將範圍與 arrays 聯結結合,您可以達成各種解巢狀,如下列使用案例所述。

使用內部聯結解巢狀

下列查詢會選取具有訂單之客戶的客戶 ID 和訂單出貨日期。FROM 子句 c.orders o 中的 SQL 延伸模組取決於別名 c

SELECT c.id, o.shipdate FROM spectrum.customers c, c.orders o

針對具有訂單的每個客戶 cFROM 子句會為客戶 c 的每個訂單 o 傳回一個資料列。該資料列會結合客戶資料列 c 和訂單資料列 o。那麼,SELECT 子句只會保留 c.ido.shipdate。結果如下所示。

id| shipdate --|---------------------- 1 |2018-03-01 11:59:59 1 |2018-03-01 09:10:00 3 |2018-03-02 08:02:15 (3 rows)

別名 c 提供客戶欄位的存取,而別名 o 則提供訂單欄位的存取。

語意類似於標準的 SQL。您可以將 FROM 子句想成執行下列巢狀迴圈,它的後面接著 SELECT 選擇要輸出的欄位。

for each customer c in spectrum.customers for each order o in c.orders output c.id and o.shipdate

因此,如果客戶沒有訂單,客戶便不會出現在結果中。

您也可以將這想成執行 JOIN 搭配 customers資料表和 orders 陣列的 FROM 子句。實際上,您也可以如下列範例所示寫入查詢。

SELECT c.id, o.shipdate FROM spectrum.customers c INNER JOIN c.orders o ON true
注意

如果名為 c 的結構描述存在於名為 orders 的資料表中,則 c.orders 會參考資料表 orders,而非 customers 的陣列資料欄。

使用左聯結解巢狀

下列查詢會輸出所有客戶名稱和其訂單。如果客戶尚未下訂單,仍會傳回客戶的名稱。不過,在此情況下,訂單資料欄會是 NULL,如以下 Jenny Doe 的範例所示。

SELECT c.id, c.name.given, c.name.family, o.shipdate, o.price FROM spectrum.customers c LEFT JOIN c.orders o ON true

前述查詢會傳回下列資料。

id | given | family | shipdate | price ----|---------|---------|----------------------|-------- 1 | John | Smith | 2018-03-01 11:59:59 | 100.5 1 | John | Smith | 2018-03-01 09:10:00 | 99.12 2 | Jenny | Doe | | 3 | Andy | Jones | 2018-03-02 08:02:15 | 13.5 (4 rows)

延伸模組 3:直接使用別名存取純量的陣列

FROM 子句中別名 p 的範圍超過純量的陣列,則查詢會完全以 p 的形式參考 p 的值。例如,以下查詢會產生客戶名稱與電話號碼的配對。

SELECT c.name.given, c.name.family, p AS phone FROM spectrum.customers c LEFT JOIN c.phones p ON true

前述查詢會傳回下列資料。

given | family | phone -------|----------|----------- John | Smith | 123-4577891 Jenny | Doe | 858-8675309 Jenny | Doe | 415-9876543 Andy | Jones | (4 rows)

延伸模組 4:存取 map 的元素

Redshift Spectrum 會將 map 資料類型視為 array 類型,其中包含的 struct 類型具有 key 資料欄和 value 資料欄。key 必須是 scalar;值可以是任何資料類型。

例如,以下程式碼會建立外部資料表,其中具有 map 用於儲存電話號碼。

CREATE EXTERNAL TABLE spectrum.customers2 ( id int, name struct<given:varchar(20), family:varchar(20)>, phones map<varchar(20), varchar(20)>, orders array<struct<shipdate:timestamp, price:double precision>> ) STORED AS PARQUET LOCATION 's3://redshift-downloads/tickit/spectrum/customers/';

因為 map 類型的行為類似具有資料欄 keyvaluearray 類型,您可以將前述結構描述想像成如下。

CREATE EXTERNAL TABLE spectrum.customers3 ( id int, name struct<given:varchar(20), family:varchar(20)>, phones array<struct<key:varchar(20), value:varchar(20)>>, orders array<struct<shipdate:timestamp, price:double precision>> ) STORED AS PARQUET LOCATION 's3://redshift-downloads/tickit/spectrum/customers/';

下列查詢會傳回具有行動電話號碼之客戶的名稱,並傳回每個名稱的號碼。映射查詢被視為與查詢 struct 類型的巢狀 array 的同等項目。下列查詢只會在您如先前所述建立了外部資料表時傳回資料。

SELECT c.name.given, c.name.family, p.value FROM spectrum.customers c, c.phones p WHERE p.key = 'mobile';
注意

mapkey 為用於 Ion 和 JSON 檔案類型的 string

隱私權網站條款Cookie 偏好設定
© 2025, Amazon Web Services, Inc.或其附屬公司。保留所有權利。