解决Cross Join重复条目问题:修改SP获取指定银行主账户
解决存储过程返回重复主账户数据的问题
问题分析
- 使用
CROSS JOIN会产生笛卡尔积:因为函数fnGetMainAccountTypeOfBank始终返回单行结果,CROSS JOIN会将关联后的每一条账户记录与这单行结果强制组合,导致原本的每条账户数据都被重复输出(逻辑上属于无效的重复匹配)。 - 核心需求是:根据传入的
bank_key,筛选出对应银行下、账户类型为该银行主账户类型的记录。
正确解决方案
方案1:先获取主账户类型再过滤
先通过函数拿到指定银行的主账户类型,再在查询中用该类型筛选账户,逻辑清晰且彻底避免笛卡尔积:
CREATE PROCEDURE GetAccountsForBank @bank_key INT AS BEGIN SET NOCOUNT ON; -- 禁止返回影响行数的消息,优化性能 -- 声明变量存储主账户类型(字段类型根据实际表结构调整) DECLARE @main_account_type NVARCHAR(100); SELECT @main_account_type = main_account_type FROM fnGetMainAccountTypeOfBank(@bank_key); -- 关联表并筛选主账户数据 SELECT a.account_id, a.account_type, a.user_id, b.bank_name, ab.link_id -- 其他需要返回的关联表字段 FROM Account a INNER JOIN Account_Bank ab ON a.account_id = ab.account_id INNER JOIN Bank b ON ab.bank_key = b.bank_key WHERE b.bank_key = @bank_key AND a.account_type = @main_account_type; END
方案2:用INNER JOIN替代CROSS JOIN
直接将函数结果与账户表通过账户类型关联,INNER JOIN只会匹配符合条件的记录,不会产生无效的笛卡尔积:
CREATE PROCEDURE GetAccountsForBank @bank_key INT AS BEGIN SET NOCOUNT ON; SELECT a.account_id, a.account_type, a.user_id, b.bank_name, ab.link_id FROM Account a INNER JOIN Account_Bank ab ON a.account_id = ab.account_id INNER JOIN Bank b ON ab.bank_key = b.bank_key -- 通过账户类型关联函数结果,精准筛选主账户 INNER JOIN fnGetMainAccountTypeOfBank(@bank_key) mat ON a.account_type = mat.main_account_type WHERE b.bank_key = @bank_key; END
注意事项
- 确保函数
fnGetMainAccountTypeOfBank返回的字段名(比如示例中的main_account_type)与Account表中的账户类型字段名完全匹配,否则需要调整关联条件。 - 根据描述“每个用户仅一个主账户”,无需额外添加用户维度的过滤,但如果业务存在特殊情况,可补充
GROUP BY a.user_id或对应的唯一约束校验。
内容的提问来源于stack exchange,提问作者Qwerty
相关产品推荐
相关产品推荐

