BigQuery中自定义视图LEFT JOIN后Margin字段返回NULL问题排查
先确认视图的聚合范围
你的视图SQL没有加GROUP BY子句,执行后会把所有符合条件的数据聚合为单条记录——也就是说视图里的Voucher_ID是所有满足条件的voucher_id中的最小值,Margin是所有记录里的最大margin值,并非每个voucher_id对应自己的聚合结果。
单独运行视图时你能看到有效数值,但这个数值只对应那个最小的voucher_id。当你用原表的所有voucher_id去LEFT JOIN时,只有和视图里那个最小voucher_id匹配的记录能拿到Margin,其他记录自然返回NULL。修正视图的分组逻辑
如果你需要的是每个voucher_id对应的聚合值,必须给视图加上GROUP BY:SELECT min(margin1.created) as CreationDate, max(margin1.margin) as Margin, min(margin1.VoucherID) as Voucher_ID, min(margin1.Price) as Price FROM ( SELECT * FROM `grouponi_groupon.tb_orders_items` OrderItem LEFT JOIN( SELECT cast (created as date) as created, order_item_cda_margin_percentage as margin, order_item_voucher_id as VoucherID, order_item_amount as Price FROM `grouponi_groupon.order_item_snapshot_clean` as MarginTable ) as MarginTable on MarginTable.VoucherID = OrderItem.voucher_id ) as margin1 WHERE cast(margin1.created as DATE) >= '2021-01-01' GROUP BY margin1.VoucherID -- 新增分组条件验证关联字段的匹配一致性
即使voucher_id在两边都存在,也要确认字段类型是否一致(比如一边是字符串,一边是整数)。可以尝试强制转换类型后再关联测试:SELECT * FROM `grouponi_groupon.tb_orders_items` OrderItem LEFT JOIN Min_Order_Margin margin1 ON CAST(OrderItem.voucher_id AS STRING) = CAST(margin1.Voucher_ID AS STRING)排查视图的过滤条件影响
视图里的WHERE cast(margin1.created as DATE) >= '2021-01-01'会过滤掉created早于2021-01-01的记录。如果原表中某些voucher_id对应的snapshot记录都在这个日期之前,视图里就不会有这些voucher_id的条目,LEFT JOIN后这些记录的Margin会返回NULL。可以临时去掉这个WHERE条件,测试是否能拿到对应数据。分步验证单条voucher_id的匹配情况
从原表中选一个确认存在的voucher_id,执行以下查询:SELECT * FROM Min_Order_Margin WHERE Voucher_ID = '你的测试voucher_id'如果没有返回结果,说明这个voucher_id的记录被视图的聚合或过滤逻辑排除了,需要进一步检查该voucher_id对应的snapshot数据是否符合视图的WHERE条件。
内容的提问来源于stack exchange,提问作者Tzahi Barda

