INNER JOIN关联两张表后行数异常增多的原因排查求助
关联两张表后结果行数远超预期的原因及解决办法
关联后出现十万多行结果,和每张表的列数无关——列数只会影响返回结果的列数,不会改变行数。真正的原因是:两张表中存在重复的ISIN值,导致多对多的关联匹配,最终产生大量交叉记录。
比如,如果tablefinance中某个ISIN有20条符合条件的记录,tablefund中同一个ISIN有50条记录,仅这一个ISIN就会生成20×50=1000条结果,多个这样的ISIN累加后,行数自然会远超单表行数。
验证重复值的方法
先排查tablefinance中符合筛选条件的ISIN重复情况:
SELECT ISIN, COUNT(*) AS fin_count FROM tablefinance WHERE Buy_Date = '2023-02-16' GROUP BY ISIN HAVING COUNT(*) > 1;
再排查tablefund中对应ISIN的重复情况:
SELECT ISIN, COUNT(*) AS fund_count FROM tablefund WHERE ISIN IN (SELECT ISIN FROM tablefinance WHERE Buy_Date = '2023-02-16') GROUP BY ISIN HAVING COUNT(*) > 1;
这两个查询会列出所有重复的ISIN及其重复次数,两者的乘积就是该ISIN贡献的结果行数。
解决办法
根据业务需求选择合适的处理方式:
- 去重后关联:如果业务上每个ISIN只需要一条记录(比如取最新日期的条目),可以先对表做去重处理再关联。例如对
tablefinance去重:
WITH distinct_fin AS ( SELECT * FROM tablefinance WHERE Buy_Date = '2023-02-16' -- 按ISIN分组,取NAV_Date最新的一条,可根据业务调整排序字段 QUALIFY ROW_NUMBER() OVER (PARTITION BY ISIN ORDER BY NAV_Date DESC) = 1 ) SELECT * FROM distinct_fin fin INNER JOIN tablefund fund ON fund.ISIN = fin.ISIN;
如果tablefund也存在重复ISIN,可对其做同样的去重处理。
- 明确多对多逻辑:如果业务确实需要保留所有匹配记录,那当前的行数是符合逻辑的,但可以调整
SELECT语句只返回需要的字段,避免冗余数据。
示例数据
tablefinance表
| NAV_Date | ISIN | ID_Security | Security_name |
|---|---|---|---|
| 2023-01-16 | XS2587965214 | 545585 | BNP |
| 2023-01-16 | XS2229000000 | 481234 | |
| 2023-01-16 | XS2301458741 | 758798 | APPLE |
tablefund表
| NAV_Date | Fund_name | ID_Position | ID_Security | ISIN |
|---|---|---|---|---|
| 2022-01-16 | Fund 1 | 100008 | 545585 | XS2587965214 |
| 2022-01-16 | Fund 1 | 199350 | 481234 | XS2229000000 |
| 2022-01-16 | Fund 1 | 115409 | 758798 | XS2301458741 |
内容的提问来源于stack exchange,提问作者Drolis___dro
相关产品推荐
相关产品推荐

