基于rep.Ref为rep.Customer补充缺失行的SQL代码问题排查
解决SQL插入缺失的(Date, Country, Customer)记录问题
你的需求本质是给每个Customer补全rep.Ref里存在的所有(Date, Country)组合——只要某个Customer在某个(Date, Country)下没有记录,就插入一条Amt为NULL的行。
原SQL的核心问题是逻辑方向错了:你用rep.Ref左连接Customer的去重集,最后筛选dca.Customer IS NULL的行,这只能找出「没有任何Customer对应这个(Date, Country)」的情况,而非「每个Customer缺失的(Date, Country)」。加过滤条件后Customer字段为NULL,是因为左连接匹配失败时dca.Customer本身就是NULL,你直接选取了这个值。
通用版(补全所有Customer的缺失组合)
INSERT INTO rep.Customer (Date, Country, Customer, Amt) SELECT ref.Date, ref.Country, custs.Customer, NULL AS Amt FROM rep.Ref ref -- 生成所有Customer与所有(Date, Country)的笛卡尔积,得到所有应存在的组合 CROSS JOIN (SELECT DISTINCT Customer FROM rep.Customer) custs -- 筛选出rep.Customer中尚未存在的组合 WHERE NOT EXISTS ( SELECT 1 FROM rep.Customer c WHERE c.Date = ref.Date AND c.Country = ref.Country AND c.Customer = custs.Customer );
带过滤条件的版本(比如只处理智利2018-12-31或特定Customer)
如果要限定Country、Date或Customer,直接在对应子查询中添加过滤条件即可:
INSERT INTO rep.Customer (Date, Country, Customer, Amt) SELECT ref.Date, ref.Country, custs.Customer, NULL AS Amt FROM ( -- 过滤目标(Date, Country) SELECT Date, Country FROM rep.Ref WHERE Country = 'Chile' AND Date = '2018-12-31' ) ref CROSS JOIN ( -- 可选:过滤目标Customer SELECT DISTINCT Customer FROM rep.Customer WHERE Customer = 'ABC' ) custs WHERE NOT EXISTS ( SELECT 1 FROM rep.Customer c WHERE c.Date = ref.Date AND c.Country = ref.Country AND c.Customer = custs.Customer );
逻辑说明
- 用
CROSS JOIN将rep.Ref的(Date, Country)集合与所有唯一Customer做笛卡尔积,得到所有理论上应该存在的记录组合; - 用
NOT EXISTS筛选出rep.Customer中还没有的组合,这些就是需要插入的缺失行。
内容的提问来源于stack exchange,提问作者Chipmunk_da
相关产品推荐
相关产品推荐

