我有一个分区表,很想使用MERGE语句,但是由于某些原因无法解决问题。
MERGE `wr_live.p_email_event` t
using `wr_live.email_event` s
on t.user_id=s.user_id and t.event=s.event and t.timestamp=s.timestamp
WHEN NOT MATCHED THEN
INSERT (user_id,event,engagement_score,dest_email_domain,timestamp,tags,meta)
values (user_id,event,engagement_score,dest_email_domain,timestamp,tags,meta)
我知道
在没有过滤器的情况下无法查询表“ wr_live.p_email_event” 可用于消除分区。
正确的语法是什么?还有一种方法可以表达较短的插入内容吗?没有命名所有列?
答案 0 :(得分:2)
正确的语法是什么?
从错误消息中可以看到-创建的分区wr_live.p_email_event
表的require partition filter
设置为true。这意味着对该表的任何查询都必须在相应的分区字段
假设timestamp
是该分区字段-您可以执行以下操作
MERGE `wr_live.p_email_event` t
USING `wr_live.email_event` s
ON t.user_id=s.user_id AND t.event=s.event AND t.timestamp=s.timestamp
AND DATE(t.timestamp) > CURRENT_DATE() -- this is the filter you should tune
WHEN NOT MATCHED THEN
INSERT (user_id,event,engagement_score,dest_email_domain,timestamp,tags,meta)
VALUES (user_id,event,engagement_score,dest_email_domain,timestamp,tags,meta)
因此,您需要进行以下修改,以使其实际上不会过滤掉您需要参与的任何事情
AND DATE(t.timestamp) <> CURRENT_DATE() -- this is the filter you should tune
例如,我发现将其设置为将来的时间戳记-在很多情况下都可以解决该问题,例如
AND DATE(t.timestamp) > DATE_ADD(CURRENT_DATE(), INTERVAL 1 DAY)
当然,如果您的wr_live.email_event
表也已将require partition filter
设置为true进行分区-您需要为s.timestamp添加相同的过滤器
还有一种方法可以表达较短的插入内容吗?没有命名所有列?
BigQuery DML的INSERT需要column names to be specified
-无法(至少据我所知)无法使用INSERT语句来避免它
同时,您可以通过从查询结果中使用DDL的CREATE TABLE来避免这种情况。不需要列出列
例如,下面的内容
CREATE OR REPLACE TABLE `wr_live.p_email_event`
PARTITION BY DATE(timestamp) AS
SELECT * FROM `wr_live.p_email_event`
WHERE DATE(timestamp) <> DATE_ADD(CURRENT_DATE(), INTERVAL 1 DAY)
UNION ALL
SELECT * FROM `wr_live.email_event` s
WHERE NOT EXISTS (
SELECT 1 FROM `wr_live.p_email_event` t
WHERE t.user_id=s.user_id AND t.event=s.event AND t.timestamp=s.timestamp
AND DATE(t.timestamp) > DATE_ADD(CURRENT_DATE(), INTERVAL 1 DAY)
)
您可能还希望通过OPTIONS()包含表选项列表-但看起来还不支持filter属性-因此,如果确实有/需要它,则上面将“擦除”此属性:o(