BigQuery:使用DML以原子方式替换日期分区

时间:2018-11-07 08:58:30

标签: sql google-bigquery

我经常想将一天的数据加载到按日期划分的BigQuery表中,以替换已经存在的任何数据。我知道如何对“旧式”数据分区表(具有_PARTITIONTIME字段的表)执行此操作,但不知道如何对新式日期分区表(使用常规日期/时间戳列以指定分区,因为它们不允许使用$装饰器。

假设我要在my_table上执行此操作。对于旧式的按日期分区的表,我通过使用$装饰器和WRITE_TRUNCATE写处置的加载作业来完成此操作-例如,我将目标表设置为{{1 }}。

但是,我不确定如何使用DML执行等效操作。我发现自己执行了单独的my_table$20181005DELETE命令。这不是很好,因为它增加了复杂性,查询数量,而且操作不是原子的。

我想知道如何使用INSERT命令来做到这一点,以使其全部包含在单个原子操作中。但是,我无法完全理解MERGE命令的语法,也没有找到此用例的示例。有谁知道该怎么做?

理想答案是DML语句,该语句从MERGE中选择了所有列,并将其插入到source_table的{​​{1}}日期分区中,删除了所有现有列2018-10-05的{​​{1}}日期分区中的数据。我们可以假设my_tablemy_table具有相同的架构,并且2018-10-05source_table列上是my_table类型的分区。

1 个答案:

答案 0 :(得分:3)

  

因为他们不允许使用$装饰器

但是它们确实可以,当您加载到基于列的分区表中时,也可以使用table_name$YYYYMMDD。例如,我做了一个分区表:

$ bq query --use_legacy_sql=false "CREATE TABLE tmp_elliottb.PartitionedTable (x INT64, y NUMERIC, date DATE) PARTITION BY date"

然后我将其加载到特定分区:

$ echo "1,3.14,2018-11-07" > row.csv
$ bq "tmp_elliottb.PartitionedTable\$20181107" ./row.csv

我试图将输入数据加载到错误的分区中,并收到错误消息:

$ echo "1,3.14,2018-11-07" > row.csv
$ bq "tmp_elliottb.PartitionedTable\$20181105" ./row.csv
Some rows belong to different partitions rather than destination partition 20181105

然后我替换了分区的数据:

$ echo "2,0.11,2018-11-07" > row.csv
$ bq "tmp_elliottb.PartitionedTable\$20181107" ./row.csv

是的,您可以使用MERGE来替换分区表分区的数据,但是您也可以使用加载作业。