解决Agent与Conta关联查询时重复Agent记录的问题
解决Agent记录重复的SQL优化方案
看起来你遇到的是典型的一对多关联导致的重复记录问题——因为一个Agent对应多个Conta,直接INNER JOIN会让每个Conta都和Agent匹配一次,自然就出现了重复的Agent条目。下面给你两种常见的解决思路,根据你的需求选择:
方案1:获取每个Agent对应的最新Conta记录
如果你需要展示每个Agent关联的最新一条Conta数据(假设Data是时间字段,按它倒序取最新),可以用窗口函数ROW_NUMBER()给每个Agent的Conta记录排序,只保留第一条:
WITH LAST_COUNT AS ( SELECT {Conta}.[AgentId], {Conta}.[Data], {Conta}.[Valor], {Conta}.[Submit], -- 按Agent分组,给Conta按Data倒序编号,第一条就是最新记录 ROW_NUMBER() OVER (PARTITION BY {Conta}.[AgentId] ORDER BY {Conta}.[Data] DESC) AS rn FROM {Conta} ) SELECT {Agent}.[Id], {Agent}.[Nome], {Agent}.[Apelido], LAST_COUNT.[Data], LAST_COUNT.[Valor], LAST_COUNT.[Submit], {AgentPicture}.[Id], {AgentPicture}.[Filename], {Agent}.[Telemovel], {Agent}.[UserId] FROM {Agent} LEFT JOIN {AgentPicture} ON {AgentPicture}.[Id] = {Agent}.[Id] -- 只关联每个Agent的第一条Conta记录(rn=1) LEFT JOIN LAST_COUNT ON LAST_COUNT.[AgentId] = {Agent}.[Id] AND LAST_COUNT.rn = 1 WHERE {Agent}.[Id] LIKE '%' + @SearchFilter + '%' OR {Agent}.[Nome] LIKE '%' + @SearchFilter + '%' OR {Agent}.[Apelido] LIKE '%' + @SearchFilter + '%' OR @SearchFilter = ''
这里把原来的INNER JOIN改成LEFT JOIN是为了确保没有关联Conta的Agent也能被展示,如果你的业务要求只显示有Conta的Agent,改回INNER JOIN即可。
方案2:聚合Conta的统计信息(不需要具体Conta数据)
如果你不需要展示单个Conta的详细数据,只是需要每个Agent的Conta相关统计(比如数量、最新日期),可以用GROUP BY聚合后再关联:
WITH CONTA_AGG AS ( SELECT {Conta}.[AgentId], COUNT(*) AS ContaCount, -- 统计该Agent的Conta总数量 MAX({Conta}.[Data]) AS LastContaDate -- 该Agent最新的Conta日期 FROM {Conta} GROUP BY {Conta}.[AgentId] ) SELECT {Agent}.[Id], {Agent}.[Nome], {Agent}.[Apelido], CONTA_AGG.ContaCount, CONTA_AGG.LastContaDate, {AgentPicture}.[Id], {AgentPicture}.[Filename], {Agent}.[Telemovel], {Agent}.[UserId] FROM {Agent} LEFT JOIN {AgentPicture} ON {AgentPicture}.[Id] = {Agent}.[Id] LEFT JOIN CONTA_AGG ON CONTA_AGG.[AgentId] = {Agent}.[Id] WHERE {Agent}.[Id] LIKE '%' + @SearchFilter + '%' OR {Agent}.[Nome] LIKE '%' + @SearchFilter + '%' OR {Agent}.[Apelido] LIKE '%' + @SearchFilter + '%' OR @SearchFilter = ''
为什么原SQL会出现重复?
原SQL里的LAST_COUNT CTE只是查询了所有Conta记录,没有做任何去重或聚合处理。当你用INNER JOIN关联Agent和这个CTE时,每个Conta都会和对应的Agent匹配一次,最终结果里的Agent条目数就等于所有Conta的总数,自然出现重复。
内容的提问来源于stack exchange,提问作者Diogo Mendes
相关产品推荐
相关产品推荐

