基于InvoiceTaskID列清除SQL重复行的解决方案求助
解决InvoiceTaskID重复行清理问题
问题原因分析
你之前的ROW_NUMBER分区逻辑错误——把所有查询字段都加入了PARTITION BY,这意味着只有当所有字段完全相同时,才会被划分到同一个分区,自然每行的RowNumber都是1。而你的需求是基于InvoiceTaskID去重,所以分区只需要聚焦这个字段即可。
解决方案
方案1:查询去重后的结果(不删除原数据)
使用CTE给每个InvoiceTaskID分组的行编号,保留每组的第一行(可根据业务规则调整排序逻辑):
WITH RankedTasks AS ( SELECT A.TaskId, A.InvoiceTaskId, A.Client, A.InvoiceId, A.Date, A.JobId, A.TaskName, A.StaffName, A.BillableRate, A.Hrs, A.Amount, D.duplicate, -- 仅按InvoiceTaskID分区,确保同ID的行在同一组 ROW_NUMBER() OVER ( PARTITION BY A.InvoiceTaskId ORDER BY A.Date DESC -- 按日期倒序,保留最新的行;可替换为TaskId等其他字段 ) AS RowNumber FROM dbo.A INNER JOIN dbo.D ON D.TaskNo = A.InvoiceTaskId ) -- 筛选出每组的第一行 SELECT * FROM RankedTasks WHERE RowNumber = 1;
方案2:直接删除重复行(保留指定规则的行)
如果需要直接清理原表中的重复行,同样用CTE实现:
WITH RankedTasks AS ( SELECT A.*, D.duplicate, ROW_NUMBER() OVER ( PARTITION BY A.InvoiceTaskId ORDER BY A.Date DESC -- 按业务需求选择保留的行,比如最新日期 ) AS RowNumber FROM dbo.A INNER JOIN dbo.D ON D.TaskNo = A.InvoiceTaskId WHERE D.duplicate > 1 -- 仅处理有重复的记录,提升效率 ) -- 删除分组中编号大于1的重复行 DELETE FROM RankedTasks WHERE RowNumber > 1;
关键说明
- 调整
ORDER BY子句可以控制保留哪一行:比如按TaskId DESC保留ID最大的行,或按Amount保留金额最高的行,完全根据你的业务需求来。 - 如果
dbo.D.duplicate字段确实准确标记了InvoiceTaskID的重复次数,加上WHERE D.duplicate > 1可以避免处理无重复的记录,减少不必要的计算。
内容的提问来源于stack exchange,提问作者Stady
相关产品推荐
相关产品推荐

