Skip to content
Last updated

データのマージ

Treasure Dataのテーブルとの間でデータをマージすることができます:

  • 1つのテーブルから既存のテーブルへのマージ
  • 2つのテーブルから3番目のテーブルへのマージは、1つ以上のソーステーブルからデータをクエリし、Treasure Data Data Exchange Export Integrationを使用して結果を新規または既存のテーブルに書き込むことで構成されます。

前提条件

  • TD Toolbeltを含むTreasure Dataの基本知識
  • Treasure Dataへのジョブ結果出力の基本的な理解

1つのテーブルを別の既存のテーブルにマージする

次のシナリオでは、ソーステーブルと宛先テーブルの両方が存在し、データが含まれています。マージは、ソーステーブルからデータをクエリし、Treasure Data Data Exchangeコネクタを使用して結果を宛先テーブルに書き込むことで構成されます。

ソーステーブルがsrc_dbs.src_tblという名前で、次のようなスキーマを持っていると仮定しましょう。

  • TD Toolbeltコマンドサンプル
$ 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は次のようなスキーマを持っています:

$ td schema:show dst_dbs dst_tbl
dst_dbs.dst_tbl (
  common_col:string
  dst_col_1:string
  dst_col_2:long
)

ソーステーブルと宛先テーブルで同じ名前を持つカラムに属するデータはマージされます - これにはtimeカラムまたはその同等のカラムが含まれます。宛先テーブルに存在しないソーステーブルのカラムは、単にコピーされます。

テーブルをマージするには、CLIで次のコマンドを実行します:

$ 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クローズで指定されたカラム)を含むように更新されます。新しいスキーマは次のようになります:

$ td schema:show dst_dbs dst_tbl
  • 結果
dst_dbs.dst_tbl (
  common_col:string
  dst_col_1:string
  dst_col_2:long
  src_col_1:string
  src_col_2:long
)

明らかに、timecommon_colの両方のデータがプロセス中にマージされました。宛先テーブルのcommon_colとソーステーブルのcommon_colのマージを避けたい場合、おそらく2つのカラムが混在すべきでない異なる意味を持つデータを含んでいる場合、簡単な方法は、SELECTクローズでソースカラムを"old_name AS new_name"の表記で名前を変更することです:

$ 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_1src_dbs_2.src_tbl_2という名前で、次のようなスキーマを持っていると仮定しましょう:

$ 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
    )
$ 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つのテーブルからのデータを新しい宛先テーブルにマージします。宛先テーブルは、クエリの結果が宛先に書き込まれるときに自動的に作成されます。

$ 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はいずれかのテーブルのカラムに名前空間を付けるために使用されます。
  • 丸括弧の最後の外側の最後のエイリアスは、構文で必要な任意の名前です。

宛先テーブルが存在し、データが含まれている場合、クエリは少し複雑になることがあります。プロセス中に望ましくないマージやカラムの上書きが発生しないように、特別な注意を払う必要があります。実際のクエリは、特定のユースケースによって大きく異なる場合があります。