Azure Data ShareからVantageに接続する方法

著者 [Rupal Shah](rupal.shah@teradata.com)
最終更新日 2022年2月14日

:::note warn
警告
本記事はTeradata Corporationのサイト[Getting Started](https://quickstarts.teradata.com/index.html#getting-access-to-vantage)に掲載された内容を抄訳したものです。掲載内容の正確性・完全性・信頼性・最新性を保証するものではございません。正確な内容については、原本をご参照下さい。
また、修正が必要な箇所や、ご要望についてはコメントをよろしくお願いします。
:::

# 概要
この記事では、Azure Data Shareサービスを使用してAzure Blob Storageデータセットをあるユーザーから別のユーザーに共有し、Teradata VantageでNative Object Store（NOS）機能を活用してクエリを実行する手順について説明します。両方のユーザーに対してストレージアカウントとデータ共有アカウントを作成し、使用することになります。

これは、ワークフローの図です。

![画像01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2742714/e0336fa5-24ba-2ee1-d90f-0cedd58316a4.png)

# Azure Data Shareについて

[Azure Data Share](https://docs.microsoft.com/en-us/azure/data-share/overview)は、企業が複数の顧客やパートナーと簡単かつ安全にデータを共有することを可能にします。データ提供者とデータ消費者の両方が、データを共有および受信するためにAzureサブスクリプションを持つ必要があります。Azure Data Shareは現在、スナップショットベースの共有とインプレース共有を提供しています。現在、Azure Data Shareが[サポートしているデータストア](https://docs.microsoft.com/en-us/azure/data-share/supported-data-stores)は、Azure Blob Storage、Azure Data Lake Storage Gen1およびGen2、Azure SQL Database、Azure Synapse Analytics、Azure Data Explorerです。Azure Data Shareを使用してデータセット共有を送信すると、データ消費者はAzure Blob Storageなどの任意のデータストアでそのデータを受け取り、Teradata Vantageを使用してデータを探索、分析することができます。

詳細については、[ドキュメント](https://docs.microsoft.com/en-us/azure/data-share/)を参照してください。


# Teradata Vantageについて

Vantageは、データウェアハウス、データレイク、アナリティクスを単一の接続されたエコシステムに統合する最新のクラウドプラットフォームです。

Vantageは、記述的分析、予測的分析、処方的分析、自律的意思決定、ML機能、可視化ツールを統合したプラットフォームで、データの所在を問わず、リアルタイムのビジネスインテリジェンスを大規模に発掘することが可能です。

Vantageは、小規模から始めて、コンピュートやストレージを弾力的に拡張し、使用した分だけ支払い、低コストのオブジェクトストアを活用し、分析ワークロードを統合することが可能です。

Vantageは、R、Python、Teradata Studio、およびその他のSQLベースのツールをサポートしています。Vantageは、パブリッククラウド、オンプレミス、最適化されたインフラ、コモディティインフラ、as-a-serviceのいずれでも導入可能です。

Teradata Vantage Native Object Store（NOS）は、標準的なSQLを使用して、Azure Blob Storageなどの外部オブジェクトストアにあるデータを探索することが可能です。NOSを使用するために、特別なオブジェクトストレージ側の計算インフラは必要ありません。コンテナを指すNOSテーブル定義を作成するだけで、Blob Storageコンテナにあるデータを探索することができます。NOSを使用すると、Blob Storageからデータを迅速にインポートしたり、データベース内の他のテーブルと結合したりすることも可能です。

また、Teradata Parallel Transporter（TPT）ユーティリティを使用して、Blob StorageからTeradata Vantageにデータを一括でインポートすることも可能です。ロードされたデータは、Vantage内で効率的にクエリすることができます。

詳細については、[ドキュメント](https://docs.teradata.com/home)を参照してください。

# 前提条件
・Teradata Vantageインスタンスにアクセスできること。

::: note info
メモ！
Vantageの新しいインスタンスが必要な場合は、[Google Cloud](https://quickstarts.teradata.com/vantage.express.gcp.html)、[Azure](https://quickstarts.teradata.com/run-vantage-express-on-microsoft-azure.html)、[AWS](https://quickstarts.teradata.com/run-vantage-express-on-aws.html)のクラウドにVantage Expressという無料版をインストールすることができます。また、[VMware](https://quickstarts.teradata.com/getting.started.vmware.html)、[VirtualBox](https://quickstarts.teradata.com/getting.started.vbox.html)、または[UTM](https://quickstarts.teradata.com/getting.started.utm.html)を使用して、ローカルマシン上でVantage Expressを実行することもできます。
:::

・Azureのアカウント。[無料アカウント](https://azure.microsoft.com/free/)で始めることができます。
・データデータセットを保存するための[Azure Blob Storage](https://docs.microsoft.com/en-us/azure/storage/common/storage-quickstart-create-account?tabs=azure-portal)アカウント。

# 手順
前提条件を満たしたら、以下の手順を実行します。

①	Azure Blob Storage アカウントとコンテナを作成します。
②	データ共有アカウントを作成する
③	共有の作成
④	データ共有を使用したデータの受信と受取り
⑤	Blob Storage への NOS アクセスを構成する
⑥	Blob Storageのデータセットにクエリを実行する
⑦	Blob StorageからVantageにデータをロードする（オプション）


# Azure Blob Storageアカウントとコンテナの作成
・ブラウザで[Azureポータル](https://portal.azure.com/)を開き（Chrome、Firefox、Safariでうまくいきます）、この記事のmyProviderStorage_rgというリソースグループに[ストレージアカウントを作成する](https://docs.microsoft.com/en-us/azure/storage/common/storage-account-create?tabs=azure-portal#create-a-storage-account-1)の手順に従います。
・ストレージ名と接続方式を入力します。今回は、myproviderstorageとpublic endpointを使用します。

::: note info
メモ！
作成するすべてのサービスに同じ場所を使用することをお勧めします。
:::

・**Review + create**を選択し、**Create**を選択します。
・[**リソース**］で［**コンテナ**］をクリックし、コンテナを作成します。
・[**コンテナ**]ボタンをクリックします。
・コンテナ名を入力します。今回はproviderdataを使用します。

![画像02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2742714/cb9b4e91-fcb6-9c6c-d76e-fc0919feb313.png)

・[**作成**］をクリックします。


# データシェアアカウントの作成
データセットを共有するプロバイダーのデータ共有アカウントを作成します。

この記事の「[Azure データ共有アカウントの作成](https://docs.microsoft.com/en-us/azure/data-share/share-your-data?tabs=azure-portal#create-a-data-share-account)」の手順に従い、myDataShareProvider_rg というリソースグループにリソースを作成します。

・**Basics** タブで、データ共有アカウント名を入力します。今回は、mydatashareprovider を使用します。

![画像03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2742714/0f6d4f90-01ce-6bf6-2b85-fe0b38af1994.png)

::: note info
メモ！
作成するすべてのサービスに同じ場所を使用することをお勧めします。
:::

・**Review + create** を選択し、**Create** を選択します。
・展開が完了したら、**Go to resource** を選択します。

# 共有の作成
・[データ共有の概要] ページに移動し、[共有を作成](https://docs.microsoft.com/en-us/azure/data-share/share-your-data?tabs=azure-portal#create-a-share) の手順に従います。
・**Start sharing your data** を選択します。
・[**作成**] を選択します。
・[**詳細**] タブで、共有名と共有タイプを入力します。今回は、WeatherDataとSnapshotを使用します。

![画像04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2742714/6d25c42d-25ed-ee62-3187-3ba853a151e2.png)

::: note info
メモ！
スナップショット共有
受信者にデータのコピーを提供するために、スナップショット共有を選択します。

サポートされているデータストア Azure Blob Storage、Azure Data Lake Storage Gen1、Azure Data Lake Storage Gen2、Azure SQL Database、Azure Synapse Analytics (旧 SQL DW)
:::

::: note info
メモ！
インプレース共有
データへのアクセスをソースで提供するために、インプレース共有を選択します。

サポートされているデータストア Azure データエクスプローラー
:::

・[**続行**]をクリックします。
・[**データセット**]タブで、[**データセットの追加**]をクリックします。
・**Azure Blob Storage** を選択します。

![画像05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2742714/344f2787-e500-7dda-90ad-d9bb9e74c165.png)

・[**次へ**」をクリックします。
・データセットを提供するストレージアカウントを入力します。今回は、myproviderstorageを使用します

![画像06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2742714/cf0426da-8a49-b76f-7d0d-b2d7a0bc9b9d.png)

・[**次へ**」をクリックします。
・コンテナをダブルクリックして、データセットを選択します。今回は providerdata と onpoint_history_postal-code_hour.csv ファイルを使用します。

![画像07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2742714/6df6cf26-6181-e395-3c75-b7dd0184b7ee.png)

図 6 ストレージコンテナとデータセットの選択

::: note info
メモ！
Azure Data Share は、フォルダレベルとファイルレベルで共有できます。ファイルのアップロードには、Azure Blob Storageリソースを使用します。
:::

・[**次へ**」をクリックします。
・コンシューマーに表示されるフォルダとデータセット名を入力します。ここでは、デフォルトの名前を使用しますが、providerdata フォルダーは削除します。[**Add datasets**］をクリックします。

![画像08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2742714/96b41748-1505-7b25-1edc-453d4bce6bd1.png)

・[**データセットの追加**］をクリックします。

![画像09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2742714/e1bf5814-32be-7bc0-650b-4fd3616b9068.png)

・[**続行**]をクリックします。
・[**受信者**]タブで、[共有通知を送信する**受信者**の電子メールアドレスを**追加する**]をクリックします。
・消費者の電子メールアドレスを入力します。

![画像10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2742714/7a49851a-fe0d-0d7e-cf58-f893b78c2ca7.png)

::: note tip
チップ！
消費者が受け入れることができるシェア有効期限を設定します。
:::

・[**続行**]をクリックします。
・[**設定**]タブで、[スナップショットのスケジュール]を設定します。今回はデフォルトでチェックを外して使用します。

![画像11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2742714/31c8dd15-5a59-4bcb-b5f1-386ab4c89f72.png)

・[**続行**］をクリックします。
・[**Review + Create**］タブで、［**Create**］をクリックします。


![画像12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2742714/547cac88-434d-76e7-2bf9-bc408969477a.png)

・これでAzureデータ共有が作成され、データ共有の受信者が招待を受け入れる準備ができました。

![画像13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2742714/722ffbf3-1947-7c07-8461-07a39d6e0f3a.png)

# Azure Data Share を使用したデータの受理と受信

この記事では、受信者/消費者が Azure Blob ストレージ アカウントにデータを受信することを想定しています。

データ共有プロバイダと同様に、データ共有の招待を受け入れる前に、コンシューマのすべての事前要件が完了していることを確認します。

・Azureのサブスクリプション。持っていない場合は、事前に https://azure.microsoft.com/free/[free account]を作成してください。
・Azure Blob Storage アカウントとコンテナ：myConsumerStorage_rg というリソース グループを作成し、アカウント名 myconsumerstorage とコンテナ consumerdata を作成します。
・Azure データ共有アカウント：myDataShareConsumer_rg というリソースグループを作成し、mydatashareconsumer というデータ共有アカウント名を作成して、データを受け入れる。

[Azure Data Shareを使用してデータを受信する](https://docs.microsoft.com/en-us/azure/data-share/subscribe-to-data-share?tabs=azure-portal)の手順に従ってください。

# イノベーションを開く
・メールには、Microsoft Azureから「Azure Data Share invitation from [yourdataprovider@domain.com](yourdataprovider@domain.com)という件名の招待状が届いています。**招待状を見る**をクリックすると、Azureで招待状を見ることができます。

![画像14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2742714/e8000d82-bfe8-89e2-8c76-6609c9b92c42.png)

・ブラウザでData Shareのイノベーションの一覧を表示するアクションです。

![画像15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2742714/5e28b057-76d1-dd0d-eadd-e0fa9f2424fd.png)

・表示したいシェアを選択します。今回はWeatherDataを選択します。

# 招待を受ける
・ターゲットデータシェアアカウント]で、データシェアを展開するサブスクリプションとリソースグループを選択するか、ここで新しいデータシェアを作成することができます。

::: note info
メモ！
プロバイダーが利用規約の承諾を必要とする場合、ダイアログボックスが表示され、利用規約に同意することを示すボックスにチェックを入れる必要があります。
:::

・Resource groupとData share accountを入力します。今回はmyDataShareConsumer_rgとmydatashareconsumerのアカウントを使用します。

![画像16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2742714/bcd80da1-afa1-270a-26e3-7cf9a3890d14.png)

・**Accept and configure**を選択すると、Share subscriptionが作成されます。

# 受信共有の設定
・[**データセット**]タブを選択します。宛先を指定するデータセットの横にあるチェックボックスをオンにします。[**ターゲットにマッピング**]を選択し、ターゲットデータストアを選択します。

![画像17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2742714/1d4ad046-49fc-c015-9514-025a10cd7100.png)

・ターゲットデータストアの種類と、データを格納するパスを選択します。この記事のスナップショットの例では、コンシューマーの Azure Blob Storage アカウント myconsumerstorage とコンテナー consumerdata を使用することにします。

::: note info
メモ！
Azure Data Shareは、異なるデータストアから、または異なるデータストアへの共有機能を含む、オープンで柔軟なデータ共有を提供します。スナップショットおよびインプレース共有を受け入れることができるサポートされたデータソースを確認します。
:::

![画像18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2742714/9048bbd1-2c12-fc0d-1211-37149942bdaf.png)

・**Map to target**をクリックします。
・マッピングが完了したら、スナップショットベースの共有のために、「**詳細**」タブをクリックし、「フルまたはインクリメンタルで[**スナップショットをトリガーする**」をクリックします。今回は、初めてプロバイダーからデータを受け取るので、フルコピーを選択します。

![画像19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2742714/7e9e7b2e-4d9e-8740-ac48-52511612c019.png)

・最終実行ステータスが成功したら、ターゲットデータストアに移動して受信したデータを表示します。**Datasets**を選択し、Target Pathにあるリンクをクリックします。
![画像20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2742714/747e550e-8b1f-4489-72e3-170fbea34071.png)

# Azure Blob Storage への NOS アクセスの構成

Native Object Store（NOS）は、Azure Blob Storageのデータを直接読み込むことができるため、明示的にデータを読み込むことなくBlob Storageのデータを探索、分析することが可能です。

# 外部テーブル定義の作成

外部テーブル定義により、Blob Storage内のデータをAdvanced SQL Engine内で簡単に参照することができ、構造化されたリレーショナル形式でデータを利用できるようになります。

::: note info
メモ！
NOSは、CSV、JSON、Parquet形式のデータをサポートしています。
:::

・Teradata Studio を使用して Vantage システムにログインします。
・次のSQLコマンドを使用して、Blob StorageコンテナにアクセスするためのAUTHORIZATIONオブジェクトを作成します。

```sql:create_autorization.sql
CREATE AUTHORIZATION DefAuth_AZ
AS DEFINER TRUSTED
USER 'myconsumerstorage' /* Storage Account Name */
PASSWORD '*****************' /* Storage Account Access Key or SAS Token */
```

○　USERの文字列は、ストレージアカウント名に置き換えてください。
○　PASSWORD の文字列は、ストレージアカウントのアクセスキーまたは SAS トークンに置き換えます。

・以下のSQLコマンドで、Blob Storage上のCSVファイルに対する外部テーブル定義を作成します。

```:sql:create_foreigntbl.sql
CREATE MULTISET FOREIGN TABLE WeatherData,
EXTERNAL SECURITY DEFINER TRUSTED DefAuth_AZ (
  Location VARCHAR(2048) CHARACTER SET UNICODE CASESPECIFIC,
  Payload DATASET INLINE LENGTH 64000 STORAGE FORMAT CSV
)
USING (
  LOCATION ('/AZ/myconsumerstorage.blob.core.windows.net/consumerdata/')
)
```

::: note info
メモ！
最低限、外部テーブルの定義には、テーブル名（WeatherData）と、オブジェクトストアのデータを指し示すロケーション句を含める必要があります。
:::

LOCATIONでは、ストレージアカウント名とコンテナ名が必要です。これを自分のストレージアカウント名とコンテナ名に置き換える必要があります。


オブジェクトに標準的な拡張子がない場合（たとえば、「.json」、「.csv」、「.parquet」）、Location...Payload列定義句も必要で、Locationフェーズにファイル名を含める必要があります。たとえば、以下のようになります。LOCATION (**AZ/<ストレージアカウント名>.blob.core.windows.net/<コンテナ>/<ファイル名>**).


外部テーブルは常にNoPI（No Primary Index）テーブルとして定義されます。

# Azure Blob Storage のデータセットにクエリを実行する

以下の SQL コマンドを実行して、データセットにクエリを実行します。

```sql:select_foreigntbl.sql
SELECT * FROM WeatherData SAMPLE 10;
```

外部テーブルには、2つのカラムしか含まれていません。LocationとPayloadです。Location はオブジェクトストアシステムにおけるアドレスである。データ自体はpayloadカラムで表現され、外部テーブルの各レコード内のpayloadの値が1つのCSV行を表現する。

![画像21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2742714/e3b4af87-a5c7-d93a-f65c-13dfcba5fd5c.png)

以下のSQLコマンドを実行し、オブジェクト内のデータに注目します。

```sql:select_payload.sql
SELECT payload..* FROM WeatherData SAMPLE 10;
```

![画像22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2742714/4e0daf3f-7cdc-3314-3453-a4a848f9b913.png)

# ビューの作成
ビューを使用すると、ペイロード属性に関連する名前を簡素化でき、オブジェクトデータに対するSQLを簡単にコーディングでき、外部テーブルのLocation参照を隠蔽できます。

::: note info
メモ！
Vantage の外部テーブルでは、オブジェクト名とカラム名の区切りに .. (ダブルドットまたはダブルピリオド) 演算子が使用されます。
:::

・以下のSQLコマンドを実行し、ビューを作成します。

```sql:replace_view.sql
REPLACE VIEW WeatherData_view AS (
  SELECT
    CAST(payload..postal_code AS VARCHAR(10)) Postal_code,
    CAST(payload..country AS CHAR(2)) Country,
    CAST(payload..time_valid_utc AS TIMESTAMP(0) FORMAT 'YYYY-MM-DDBHH:MI:SS') Time_Valid_UTC,
    CAST(payload..doy_utc AS INTEGER) DOY_UTC,
    CAST(payload..hour_utc AS INTEGER) Hour_UTC,
    CAST(payload..time_valid_lcl AS TIMESTAMP(0) FORMAT 'YYYY-MM-DDBHH:MI:SS') Time_Valid_LCL,
    CAST(payload..dst_offset_minutes AS INTEGER) DST_Offset_Minutes,
    CAST(payload..temperature_air_2m_f AS DECIMAL(4,1)) Temperature_Air_2M_F,
    CAST(payload..temperature_wetbulb_2m_f AS DECIMAL(3,1)) Temperature_Wetbulb_2M_F,
    CAST(payload..temperature_dewpoint_2m_f AS DECIMAL(3,1)) Temperature_Dewpoint_2M_F,
    CAST(payload..temperature_feelslike_2m_f AS DECIMAL(4,1)) Temperature_Feelslike_2M_F,
    CAST(payload..temperature_windchill_2m_f AS DECIMAL(4,1)) Temperature_Windchill_2M_F,
    CAST(payload..temperature_heatindex_2m_f AS DECIMAL(4,1)) Temperature_Heatindex_2M_F,
    CAST(payload..humidity_relative_2m_pct AS DECIMAL(3,1)) Humidity_Relative_2M_Pct,
    CAST(payload..humidity_specific_2m_gpkg AS DECIMAL(3,1)) Humdity_Specific_2M_GPKG,
    CAST(payload..pressure_2m_mb AS DECIMAL(5,1)) Pressure_2M_Mb,
    CAST(payload..pressure_tendency_2m_mb AS DECIMAL(2,1)) Pressure_Tendency_2M_Mb,
    CAST(payload..pressure_mean_sea_level_mb AS DECIMAL(5,1)) Pressure_Mean_Sea_Level_Mb,
    CAST(payload..wind_speed_10m_mph AS DECIMAL(3,1)) Wind_Speed_10M_MPH,
    CAST(payload..wind_direction_10m_deg AS DECIMAL(4,1)) Wind_Direction_10M_Deg,
    CAST(payload..wind_speed_80m_mph AS DECIMAL(3,1)) Wind_Speed_80M_MPH,
    CAST(payload..wind_direction_80m_deg AS DECIMAL(4,1)) Wind_Direction_80M_Deg,
    CAST(payload..wind_speed_100m_mph AS DECIMAL(3,1)) Wind_Speed_100M_MPH,
    CAST(payload..wind_direction_100m_deg AS DECIMAL(4,1)) Wind_Direction_100M_Deg,
    CAST(payload..precipitation_in AS DECIMAL(3,2)) Precipitation_in,
    CAST(payload..snowfall_in AS DECIMAL(3,2)) Snowfall_in,
    CAST(payload..cloud_cover_pct AS INTEGER) Cloud_Cover_Pct,
    CAST(payload..radiation_solar_total_wpm2 AS DECIMAL(5,1)) Radiation_Solar_Total_WPM2
  FROM WeatherData
)
```

・以下のSQLコマンドを実行して、ビューを検証してください。

```sql:select_view.sql
SELECT * FROM WeatherData_view SAMPLE 10;
```

![画像23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2742714/e1b388cd-ea6a-9467-d65a-fc8ca1a433d7.png)

ビューを作成した後は、オブジェクト ストアのデータをクエリで簡単に参照し、他のテーブル（Vantage のリレーショナル テーブルとオブジェクト ストアの外部テーブルの両方）と結合することができます。これにより、データがどこにあっても、Vantageの完全な分析機能を100%活用することができます。

# Blob StorageからVantageへのデータのロード（オプション）

Blob Storageデータの永続的なコピーを持つことは、同じデータに繰り返しアクセスすることが予想される場合に便利です。NOS では、Blob Storage データの永続的なコピーは自動的に作成されません。外部テーブルを参照するたびに、VantageはBlob Storageからデータをフェッチします。(一部のデータはキャッシュされることがありますが、これは Blob Storage 内のデータのサイズと Vantage の他のアクティブなワークロードに依存します)。

また、Blob Storage から転送されるデータに対してネットワーク料金が課金される場合があります。Blob Storage内のデータを複数回参照する場合は、一時的にでもVantageにロードすることでコストを削減することができます。

Vantageにデータをロードする方法は、以下の中から選択できます。


#  1つのステートメントでテーブルの作成とデータの読み込みを行う
1 つのステートメントで、テーブルの作成とデータのロードの両方を行うことができます。外部テーブルのペイロードから必要な属性を選択し、それらがリレーショナルテーブルでどのように呼ばれるかを選択することができます。

**CREATE TABLE AS** ... **WITH DATA**ステートメントは、ソーステーブルとして外部テーブル定義を使用することができます。

・以下のSQLコマンドを実行してリレーショナル・テーブルを作成しデータをロードします。

```sql:create_AsWithData.sql
CREATE MULTISET TABLE WeatherData_temp AS (
  SELECT
    CAST(payload..postal_code AS VARCHAR(10)) Postal_code,
    CAST(payload..country AS CHAR(2)) Country,
    CAST(payload..time_valid_utc AS TIMESTAMP(0) FORMAT 'YYYY-MM-DDBHH:MI:SS') Time_Valid_UTC,
    CAST(payload..doy_utc AS INTEGER) DOY_UTC,
    CAST(payload..hour_utc AS INTEGER) Hour_UTC,
    CAST(payload..time_valid_lcl AS TIMESTAMP(0) FORMAT 'YYYY-MM-DDBHH:MI:SS') Time_Valid_LCL,
    CAST(payload..dst_offset_minutes AS INTEGER) DST_Offset_Minutes,
    CAST(payload..temperature_air_2m_f AS DECIMAL(4,1)) Temperature_Air_2M_F,
    CAST(payload..temperature_wetbulb_2m_f AS DECIMAL(3,1)) Temperature_Wetbulb_2M_F,
    CAST(payload..temperature_dewpoint_2m_f AS DECIMAL(3,1)) Temperature_Dewpoint_2M_F,
    CAST(payload..temperature_feelslike_2m_f AS DECIMAL(4,1)) Temperature_Feelslike_2M_F,
    CAST(payload..temperature_windchill_2m_f AS DECIMAL(4,1)) Temperature_Windchill_2M_F,
    CAST(payload..temperature_heatindex_2m_f AS DECIMAL(4,1)) Temperature_Heatindex_2M_F,
    CAST(payload..humidity_relative_2m_pct AS DECIMAL(3,1)) Humidity_Relative_2M_Pct,
    CAST(payload..humidity_specific_2m_gpkg AS DECIMAL(3,1)) Humdity_Specific_2M_GPKG,
    CAST(payload..pressure_2m_mb AS DECIMAL(5,1)) Pressure_2M_Mb,
    CAST(payload..pressure_tendency_2m_mb AS DECIMAL(2,1)) Pressure_Tendency_2M_Mb,
    CAST(payload..pressure_mean_sea_level_mb AS DECIMAL(5,1)) Pressure_Mean_Sea_Level_Mb,
    CAST(payload..wind_speed_10m_mph AS DECIMAL(3,1)) Wind_Speed_10M_MPH,
    CAST(payload..wind_direction_10m_deg AS DECIMAL(4,1)) Wind_Direction_10M_Deg,
    CAST(payload..wind_speed_80m_mph AS DECIMAL(3,1)) Wind_Speed_80M_MPH,
    CAST(payload..wind_direction_80m_deg AS DECIMAL(4,1)) Wind_Direction_80M_Deg,
    CAST(payload..wind_speed_100m_mph AS DECIMAL(3,1)) Wind_Speed_100M_MPH,
    CAST(payload..wind_direction_100m_deg AS DECIMAL(4,1)) Wind_Direction_100M_Deg,
    CAST(payload..precipitation_in AS DECIMAL(3,2)) Precipitation_in,
    CAST(payload..snowfall_in AS DECIMAL(3,2)) Snowfall_in,
    CAST(payload..cloud_cover_pct AS INTEGER) Cloud_Cover_Pct,
    CAST(payload..radiation_solar_total_wpm2 AS DECIMAL(5,1)) Radiation_Solar_Total_WPM2
  FROM
    WeatherData
  WHERE
    Postal_Code = '36101'
)
WITH DATA
NO PRIMARY INDEX
```
・以下のSQLコマンドを実行し、テーブルの内容を検証します。

```sql:select_createdtbl.sql
SELECT * FROM WeatherData_temp SAMPLE 10;
```

![画像24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2742714/0491a061-c156-98f6-0d79-7f96879e286d.png)

# 複数のステートメントでテーブルを作成し、データをロードする

複数のステートメントを使用して、最初にリレーショナルテーブルを作成し、その後データをロードすることもできます。この方法の利点は、複数回のロードが可能であることです。

・次のSQLコマンドを実行して、リレーショナルテーブルを作成します。

```sql:create_targettbl.sql
CREATE MULTISET TABLE WeatherData_temp (
  Postal_code VARCHAR(10),
  Country CHAR(2),
  Time_Valid_UTC TIMESTAMP(0) FORMAT 'YYYY-MM-DDBHH:MI:SS',
  DOY_UTC INTEGER,
  Hour_UTC INTEGER,
  Time_Valid_LCL TIMESTAMP(0) FORMAT 'YYYY-MM-DDBHH:MI:SS',
  DST_Offset_Minutes INTEGER,
  Temperature_Air_2M_F DECIMAL(4,1),
  Temperature_Wetbulb_2M_F DECIMAL(3,1),
  Temperature_Dewpoint_2M_F DECIMAL(3,1),
  Temperature_Feelslike_2M_F DECIMAL(4,1),
  Temperature_Windchill_2M_F DECIMAL(4,1),
  Temperature_Heatindex_2M_F DECIMAL(4,1),
  Humidity_Relative_2M_Pct DECIMAL(3,1),
  Humdity_Specific_2M_GPKG DECIMAL(3,1),
  Pressure_2M_Mb DECIMAL(5,1),
  Pressure_Tendency_2M_Mb DECIMAL(2,1),
  Pressure_Mean_Sea_Level_Mb DECIMAL(5,1),
  Wind_Speed_10M_MPH DECIMAL(3,1),
  Wind_Direction_10M_Deg DECIMAL(4,1),
  Wind_Speed_80M_MPH DECIMAL(3,1),
  Wind_Direction_80M_Deg DECIMAL(4,1),
  Wind_Speed_100M_MPH DECIMAL(3,1),
  Wind_Direction_100M_Deg DECIMAL(4,1),
  Precipitation_in DECIMAL(3,2),
  Snowfall_in DECIMAL(3,2),
  Cloud_Cover_Pct INTEGER,
  Radiation_Solar_Total_WPM2 DECIMAL(5,1)
)
UNIQUE PRIMARY INDEX ( Postal_Code, Time_Valid_UTC )
```


・以下のSQLを実行し、テーブルにデータをロードします。

```sql:insertselect.sql
INSERT INTO WeatherData_temp
  SELECT
    CAST(payload..postal_code AS VARCHAR(10)) Postal_code,
    CAST(payload..country AS CHAR(2)) Country,
    CAST(payload..time_valid_utc AS TIMESTAMP(0) FORMAT 'YYYY-MM-DDBHH:MI:SS') Time_Valid_UTC,
    CAST(payload..doy_utc AS INTEGER) DOY_UTC,
    CAST(payload..hour_utc AS INTEGER) Hour_UTC,
    CAST(payload..time_valid_lcl AS TIMESTAMP(0) FORMAT 'YYYY-MM-DDBHH:MI:SS') Time_Valid_LCL,
    CAST(payload..dst_offset_minutes AS INTEGER) DST_Offset_Minutes,
    CAST(payload..temperature_air_2m_f AS DECIMAL (4,1)) Temperature_Air_2M_F,
    CAST(payload..temperature_wetbulb_2m_f AS DECIMAL(3,1)) Temperature_Wetbulb_2M_F,
    CAST(payload..temperature_dewpoint_2m_f AS DECIMAL(3,1)) Temperature_Dewpoint_2M_F,
    CAST(payload..temperature_feelslike_2m_f AS DECIMAL(4,1)) Temperature_Feelslike_2M_F,
    CAST(payload..temperature_windchill_2m_f AS DECIMAL(4,1)) Temperature_Windchill_2M_F,
    CAST(payload..temperature_heatindex_2m_f AS DECIMAL(4,1)) Temperature_Heatindex_2M_F,
    CAST(payload..humidity_relative_2m_pct AS DECIMAL(3,1)) Humidity_Relative_2M_Pct,
    CAST(payload..humidity_specific_2m_gpkg AS DECIMAL(3,1)) Humdity_Specific_2M_GPKG,
    CAST(payload..pressure_2m_mb AS DECIMAL(5,1)) Pressure_2M_Mb,
    CAST(payload..pressure_tendency_2m_mb AS DECIMAL(2,1)) Pressure_Tendency_2M_Mb,
    CAST(payload..pressure_mean_sea_level_mb AS DECIMAL(5,1)) Pressure_Mean_Sea_Level_Mb,
    CAST(payload..wind_speed_10m_mph AS DECIMAL(3,1)) Wind_Speed_10M_MPH,
    CAST(payload..wind_direction_10m_deg AS DECIMAL(4,1)) Wind_Direction_10M_Deg,
    CAST(payload..wind_speed_80m_mph AS DECIMAL(3,1)) Wind_Speed_80M_MPH,
    CAST(payload..wind_direction_80m_deg AS DECIMAL(4,1)) Wind_Direction_80M_Deg,
    CAST(payload..wind_speed_100m_mph AS DECIMAL(3,1)) Wind_Speed_100M_MPH,
    CAST(payload..wind_direction_100m_deg AS DECIMAL(4,1)) Wind_Direction_100M_Deg,
    CAST(payload..precipitation_in AS DECIMAL(3,2)) Precipitation_in,
    CAST(payload..snowfall_in AS DECIMAL(3,2)) Snowfall_in,
    CAST(payload..cloud_cover_pct AS INTEGER) Cloud_Cover_Pct,
    CAST(payload..radiation_solar_total_wpm2 AS DECIMAL(5,1)) Radiation_Solar_Total_WPM2
  FROM
    WeatherData
  WHERE
    Postal_Code = '30301'
```


・以下のSQLコマンドを実行して、テーブルの内容を検証してください。

```sql:select_tergettbl.sql
SELECT * FROM WeatherData_temp SAMPLE 10;
```

![画像25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2742714/09557216-fa61-9c07-ba42-3cf1c2f26ada.png)

# READ_NOS - 外部テーブルの代替方法

外部テーブルを定義する代わりに、**READ_NOS** テーブル演算子を使用する方法があります。このテーブル演算子を使うと、最初に外部テーブルを作成することなく、オブジェクトストアから直接データにアクセスしたり、Location句で指定されたすべてのオブジェクトに関連するキーの一覧を表示したりすることができます。

**READ_NOS** テーブル演算子を使用すると、オブジェクト内のデータを探索することができます。

・以下のコマンドを実行して、オブジェクト内のデータを調査してください。

```sql:select_payload.sql
SELECT
  TOP 5 payload..*
FROM
  READ_NOS (
    ON (SELECT CAST( NULL AS DATASET STORAGE FORMAT CSV))
    USING
      LOCATION ('/AZ/myconsumerstorage.blob.core.windows.net/consumerdata')
      ACCESS_ID('myconsumerstorage')
      ACCESS_KEY('*****')
  ) AS THE_TABLE
  ORDER BY 1
```

○　LOCATIONでは、ストレージアカウント名とコンテナ名が必要です。これは、上記の黄色でハイライトされています。これを自分のストレージアカウント名とコンテナ名で置き換える必要があります。
○　ACCESS_IDの文字列を、ストレージアカウント名で置き換えます。
○　ACCES_KEYの文字列を、ストレージアカウントのアクセスキーまたはSASトークンに置き換えます。

![画像26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2742714/2970e31c-deb9-457a-bf14-8d95907b418a.png)

また、READ_NOSテーブル演算子を活用して、オブジェクトの長さ（サイズ）を取得することも可能です。

・以下のSQLコマンドを実行すると、オブジェクトのサイズが表示されます。

```sql:select_objectlength.sql
SELECT
  location(CHAR(120)), ObjectLength
FROM
  READ_NOS (
    ON (SELECT CAST( NULL AS DATASET STORAGE FORMAT CSV))
    USING
      LOCATION ('/AZ/myconsumerstorage.blob.core.windows.net/consumerdata')
      ACCESS_ID('myconsumerstorage')
      ACCESS_KEY('*****')
      RETURNTYPE('NOSREAD_KEYS')
  ) AS THE_TABLE
ORDER BY 1
```

○　LOCATION、ACCESS_ID、ACCESS_KEYの値を入れ替えてください。

![画像27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2742714/7c7041eb-3a46-7eee-2e64-a8a0ee3df222.png)

NOS_READテーブル演算子は、上記セクションの外部テーブル定義で、データをリレーショナルテーブルに読み込むために代用することができます。

```sql:create_tblusingReadNOS.sql
CREATE MULTISET TABLE WeatherData_temp AS (
  SELECT
    CAST(payload..postal_code AS VARCHAR(10)) Postal_code,
    CAST(payload..country AS CHAR(2)) Country,
    CAST(payload..time_valid_utc AS TIMESTAMP(0) FORMAT 'YYYY-MM-DDBHH:MI:SS') Time_Valid_UTC,
    CAST(payload..doy_utc AS INTEGER) DOY_UTC,
    CAST(payload..hour_utc AS INTEGER) Hour_UTC,
    CAST(payload..time_valid_lcl AS TIMESTAMP(0) FORMAT 'YYYY-MM-DDBHH:MI:SS') Time_Valid_LCL,
    CAST(payload..dst_offset_minutes AS INTEGER) DST_Offset_Minutes,
    CAST(payload..temperature_air_2m_f AS DECIMAL (4,1)) Temperature_Air_2M_F,
    CAST(payload..temperature_wetbulb_2m_f AS DECIMAL(3,1)) Temperature_Wetbulb_2M_F,
    CAST(payload..temperature_dewpoint_2m_f AS DECIMAL(3,1)) Temperature_Dewpoint_2M_F,
    CAST(payload..temperature_feelslike_2m_f AS DECIMAL(4,1)) Temperature_Feelslike_2M_F,
    CAST(payload..temperature_windchill_2m_f AS DECIMAL(4,1)) Temperature_Windchill_2M_F,
    CAST(payload..temperature_heatindex_2m_f AS DECIMAL(4,1)) Temperature_Heatindex_2M_F,
    CAST(payload..humidity_relative_2m_pct AS DECIMAL(3,1)) Humidity_Relative_2M_Pct,
    CAST(payload..humidity_specific_2m_gpkg AS DECIMAL(3,1)) Humdity_Specific_2M_GPKG,
    CAST(payload..pressure_2m_mb AS DECIMAL(5,1)) Pressure_2M_Mb,
    CAST(payload..pressure_tendency_2m_mb AS DECIMAL(2,1)) Pressure_Tendency_2M_Mb,
    CAST(payload..pressure_mean_sea_level_mb AS DECIMAL(5,1)) Pressure_Mean_Sea_Level_Mb,
    CAST(payload..wind_speed_10m_mph AS DECIMAL(3,1)) Wind_Speed_10M_MPH,
    CAST(payload..wind_direction_10m_deg AS DECIMAL(4,1)) Wind_Direction_10M_Deg,
    CAST(payload..wind_speed_80m_mph AS DECIMAL(3,1)) Wind_Speed_80M_MPH,
    CAST(payload..wind_direction_80m_deg AS DECIMAL(4,1)) Wind_Direction_80M_Deg,
    CAST(payload..wind_speed_100m_mph AS DECIMAL(3,1)) Wind_Speed_100M_MPH,
    CAST(payload..wind_direction_100m_deg AS DECIMAL(4,1)) Wind_Direction_100M_Deg,
    CAST(payload..precipitation_in AS DECIMAL(3,2)) Precipitation_in,
    CAST(payload..snowfall_in AS DECIMAL(3,2)) Snowfall_in,
    CAST(payload..cloud_cover_pct AS INTEGER) Cloud_Cover_Pct,
    CAST(payload..radiation_solar_total_wpm2 AS DECIMAL(5,1)) Radiation_Solar_Total_WPM2
  FROM
    READ_NOS (
      ON (SELECT CAST( NULL AS DATASET STORAGE FORMAT CSV))
      USING
        LOCATION ('/AZ/myconsumerstorage.blob.core.windows.net/consumerdata')
        ACCESS_ID('myconsumerstorage')
        ACCESS_KEY('*****')
    ) AS THE_TABLE
  WHERE
    Postal_Code = '36101'
)
WITH DATA
```

#### Teradata Vantageへのお問合せ
[Teradata Vantage へのお問合せ](https://www.teradata.jp/About-Us/Contact)