正确的语法是什么?
您可以从错误消息中看到 - 您的分区 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() 包含表格选项列表 - 但看起来尚不支持过滤器属性 - 因此,如果您确实拥有/需要它 - 上面将“删除”此属性:o(