# データのマージ Treasure Dataのテーブルとの間でデータをマージすることができます: * 1つのテーブルから既存のテーブルへのマージ * 2つのテーブルから3番目のテーブルへのマージは、1つ以上のソーステーブルからデータをクエリし、[Treasure Data Data Exchange Export Integration](https://docs.treasuredata.com/smart/project-integrations/treasure-data-data-exchange-export-integration)を使用して結果を新規または既存のテーブルに書き込むことで構成されます。 ## 前提条件 * TD Toolbeltを含むTreasure Dataの基本知識 * Treasure Dataへのジョブ結果出力の基本的な理解 ## 1つのテーブルを別の既存のテーブルにマージする 次のシナリオでは、ソーステーブルと宛先テーブルの両方が存在し、データが含まれています。マージは、ソーステーブルからデータをクエリし、Treasure Data Data Exchangeコネクタを使用して結果を宛先テーブルに書き込むことで構成されます。 ソーステーブルが`src_dbs.src_tbl`という名前で、次のようなスキーマを持っていると仮定しましょう。 - TD Toolbeltコマンドサンプル ```bash $ td schema:show src_dbs src_tbl ``` - レスポンスサンプル ``` src_dbs.src_tbl ( common_col:string src_col_1:string src_col_2:long ) ``` timeカラムは暗黙的です。詳細については、スキーマドキュメントページを参照してください。 そして、宛先テーブル`dst_dbs.dst_tbl`は次のようなスキーマを持っています: ```bash $ td schema:show dst_dbs dst_tbl ``` ``` dst_dbs.dst_tbl ( common_col:string dst_col_1:string dst_col_2:long ) ``` ソーステーブルと宛先テーブルで同じ名前を持つカラムに属するデータはマージされます - これには**time**カラムまたはその同等のカラムが含まれます。宛先テーブルに存在しないソーステーブルのカラムは、単にコピーされます。 テーブルをマージするには、CLIで次のコマンドを実行します: ```bash $ td query -d src_dbs -w -r 'td://@/dst_dbs/dst_tbl' \ 'SELECT `time`, src_col_1, src_col_2, common_col FROM src_tbl' ``` 結果を宛先テーブルに書き込む際に元のタイムスタンプを保持するために、timeカラムを選択します。timeカラムが省略された場合、代わりにクエリが実行された時刻が使用されます。 `td://@/dst_dbs/dst_tbl`をジョブ結果出力ターゲットとして使用することで、結果は**append**モードで書き込まれ、このクエリの結果が宛先テーブル`dst_dbs.dst_tbl`の既存のデータに追加されます。クエリが完了すると、宛先テーブルのスキーマは、以前は存在しなかったソーステーブルの結果のカラム(つまり、クエリのselectクローズで指定されたカラム)を含むように更新されます。新しいスキーマは次のようになります: ```bash $ td schema:show dst_dbs dst_tbl ``` - 結果 ```bash dst_dbs.dst_tbl ( common_col:string dst_col_1:string dst_col_2:long src_col_1:string src_col_2:long ) ``` 明らかに、`time`と`common_col`の両方のデータがプロセス中にマージされました。宛先テーブルの`common_col`とソーステーブルの`common_col`のマージを避けたい場合、おそらく2つのカラムが混在すべきでない異なる意味を持つデータを含んでいる場合、簡単な方法は、SELECTクローズでソースカラムを"`old_name AS new_name`"の表記で名前を変更することです: ```bash $ td query ... 'SELECT `time`, src_col_1, src_col_2, common_col AS src_common_col FROM src_tbl' ``` ## 2つのテーブルを3番目のテーブルにマージする 次のシナリオでは、2つのテーブルからデータをマージします。新しいテーブルに書き込む場合でも既存のテーブルに書き込む場合でも、アプローチは非常に似ています。前述したスキーマの注意事項もここに適用されます。 2つのソーステーブルが`src_dbs_1.src_tbl_1`と`src_dbs_2.src_tbl_2`という名前で、次のようなスキーマを持っていると仮定しましょう: ```bash $ td schema:show src_dbs_1 src_tbl_1 src_dbs_1.src_tbl_1 ( common_col:string src_col_1_1:string src_col_1_2:long ) ``` ```bash $ td schema:show src_dbs_2 src_tbl_2 src_dbs_2.src_tbl_2 ( common_col:string src_col_2_1:string src_col_2_2:long ) ``` 簡単のため、宛先データベース`dst_dbs`は存在するが、宛先テーブル`dst_dbs.dst_tbl`は存在しないと仮定しましょう(スキーマ更新の簡素化のため)。 このクエリは、2つのテーブルからのデータを新しい宛先テーブルにマージします。宛先テーブルは、クエリの結果が宛先に書き込まれるときに自動的に作成されます。 ```bash $ td query -d src_dbs_1 -w -r 'td://@/dst_dbs/dst_tbl' \ 'SELECT * FROM ( SELECT tbl_1_alias.time, tbl_1_alias.common_col, tbl_1_alias.src_col_1_1, tbl_1_alias.src_col_1_2, NULL as src_col_2_1, NULL as src_col_2_2 FROM src_dbs_1.src_tbl_1 tbl_1_alias UNION ALL SELECT tbl_2_alias.time, tbl_2_alias.common_col, NULL as src_col_1_1, NULL as src_col_1_2 tbl_2_alias.src_col_2_1, tbl_2_alias.src_col_2_2 FROM src_dbs_2.src_tbl_2 tbl_2_alias ) tbl_1_union_tbl_2' ``` 次の詳細に注意してください: * UNION ALLを使用して、削除または重複排除なしで、2つのソーステーブルで同一の名前を持つカラムの内容をマージします(この例では`common_col`) - UNION ALLは、各テーブルの2つの内側のselectクローズにそれらを含めることで、両方のテーブルのレコードの元のタイムスタンプも保持します。したがって、マージするカラムがなくても、timeカラムをマージするためにUNION ALLが必要です。 * **UNION ALLでは、ユニオンの両側に同じ数、名前、型のカラムが含まれている必要があります。**したがって、カラムプレースホルダーとして機能するように、最初のソーステーブルに存在しない2番目のソーステーブルのカラムを`NULL as tbl_2_col_X`として指定する必要があり、その逆も同様です。このプロセスは、テーブルに多くの無関係なカラムが含まれている場合、非常に複雑になる可能性があります。 * 2つのソーステーブルが同じデータベースに存在する場合、2つ(またはそれ以上)の内側のFROMクローズで指定されたデータベースを削除できます。 * 両方のソーステーブルは、`src_dbs_2.src_tbl_2 tbl_2_alias`構文でエイリアスを付ける必要があり、`tbl_2_alias`はいずれかのテーブルのカラムに名前空間を付けるために使用されます。 * 丸括弧の最後の外側の最後のエイリアスは、構文で必要な任意の名前です。 宛先テーブルが存在し、データが含まれている場合、クエリは少し複雑になることがあります。プロセス中に望ましくないマージやカラムの上書きが発生しないように、特別な注意を払う必要があります。実際のクエリは、特定のユースケースによって大きく異なる場合があります。