如何避免SOLine与SOLineSplit关联查询重复记录?能否用SQL视图?
解决SOLine与SOLineSplit关联重复及视图使用建议
嘿,我之前做报表的时候也碰到过类似的关联重复问题,给你分享几个实用的解决思路,还有关于视图的建议:
一、避免关联查询重复记录的方法
重复记录大多是因为SOLine和SOLineSplit是一对多的关系(一条销售行对应多个拆分记录),直接关联会把主表(SOLine)的记录按子表(SOLineSplit)的条数重复输出。根据你的报表需求,可以选下面的方案:
1. 聚合子表数据(适合展示汇总信息)
如果报表只需要SOLine的汇总数据(比如每条销售行的总拆分数量、总金额),用GROUP BY聚合子表字段,这样就能得到唯一的SOLine记录:
SELECT sl.ID AS SOLineID, sl.OrderNbr, sl.ItemID, sl.Description, SUM(ss.Qty) AS TotalSplitQty, SUM(ss.Amount) AS TotalSplitAmount FROM SOLine sl LEFT JOIN SOLineSplit ss ON sl.ID = ss.SOLineID GROUP BY sl.ID, sl.OrderNbr, sl.ItemID, sl.Description;
注意:GROUP BY要包含所有非聚合的主表字段,避免数据库报错
2. 标记重复行(适合展示明细拆分)
如果需要展示每条拆分记录,但不想重复显示SOLine的基础信息(比如订单号、商品ID),可以用窗口函数给同一SOLine下的拆分记录标序号,只在第一条显示主表信息:
SELECT CASE WHEN rn = 1 THEN sl.ID ELSE NULL END AS SOLineID, CASE WHEN rn = 1 THEN sl.OrderNbr ELSE NULL END AS OrderNbr, CASE WHEN rn = 1 THEN sl.ItemID ELSE NULL END AS ItemID, ss.ID AS SplitID, ss.Qty AS SplitQty, ss.Amount AS SplitAmount FROM ( SELECT sl.*, ss.*, ROW_NUMBER() OVER(PARTITION BY sl.ID ORDER BY ss.ID) AS rn FROM SOLine sl LEFT JOIN SOLineSplit ss ON sl.ID = ss.SOLineID ) AS combined;
这样报表里同一销售行的拆分记录,只有第一条会显示主表信息,其余行的主表字段为空,视觉上不会重复。
3. 排查关联逻辑
如果以上方法还是有重复,检查下是不是关联条件有误:
- 有没有多关联了其他表导致笛卡尔积?
- SOLineSplit表里有没有重复的关联记录?可以用
SELECT DISTINCT SOLineID, Qty, Amount FROM SOLineSplit先去重再关联。
二、关于SQL视图的使用
完全可以用SQL视图!而且非常适合你的场景:
- 视图可以把你整理好的去重/聚合逻辑封装起来,报表直接查询视图就行,不用每次写复杂的关联语句;
- 因为你只做数据展示,不需要插入/更新,普通的非物化视图就足够了(如果报表查询性能要求高,部分数据库支持物化视图,提前把数据计算好存在磁盘上);
- 视图还能统一数据口径,避免不同报表写不同查询导致的不一致。
举个创建视图的例子(基于上面的聚合查询):
CREATE VIEW vw_SalesLine_Summary AS SELECT sl.ID AS SOLineID, sl.OrderNbr, sl.ItemID, SUM(ss.Qty) AS TotalSplitQty, SUM(ss.Amount) AS TotalSplitAmount FROM SOLine sl LEFT JOIN SOLineSplit ss ON sl.ID = ss.SOLineID GROUP BY sl.ID, sl.OrderNbr, sl.ItemID;
之后报表直接查SELECT * FROM vw_SalesLine_Summary就可以了。
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

