You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何删除SQL表单行内的重复值?以deployment表为例

优化SQL行内重复ID去重并合并的方案

问题回顾

你需要对deployment表按日期分组,将每行task1-task4列中的人员ID去重后合并为逗号分隔的列表,现有自定义函数实现,但想寻找更优方案。

现有方案的问题

你的自定义函数存在几个明显缺陷:

  • 分隔符不一致:用concat拼接ID时使用;,但string_split却用,拆分,导致无法正确拆分ID,最终结果会把整个拼接字符串当作单个元素
  • 未处理NULL值:若某个task列为NULL,拼接后会出现连续的;,拆分后会引入空字符串
  • 性能瓶颈:标量函数是逐行执行的,当表数据量较大时,性能远低于集合式操作

更优实现方案

方案1:使用UNPIVOT(SQL Server 2005+支持)

通过UNPIVOT将多列的task数据转为行数据,再按日期分组去重后用STRING_AGG合并,这是最简洁高效的集合式操作:

SELECT 
    date,
    STRING_AGG(DISTINCT task_id, ', ') AS ids
FROM deployment
UNPIVOT (
    task_id FOR tasks IN (task1, task2, task3, task4)
) AS unpivoted
GROUP BY date;

方案2:使用CROSS APPLY VALUES(兼容更多SQL Server版本)

如果你的SQL Server版本不支持UNPIVOT,可以用CROSS APPLY结合VALUES实现列转行,效果一致:

SELECT 
    d.date,
    STRING_AGG(DISTINCT v.task_id, ', ') AS ids
FROM deployment d
CROSS APPLY (
    VALUES (task1), (task2), (task3), (task4)
) AS v(task_id)
WHERE v.task_id IS NOT NULL  -- 过滤NULL值
GROUP BY d.date;

方案优势

  • 性能更优:集合式操作避免了逐行调用函数的开销,数据量越大优势越明显
  • 逻辑清晰:通过列转行+分组去重+合并的流程完成需求,代码可读性高
  • 自动处理异常:自动过滤NULL值,不会引入空字符串或错误拆分的问题
  • 无需维护函数:不需要额外维护自定义函数,降低代码复杂度

内容的提问来源于stack exchange,提问作者Minh Nghĩa Nguyễn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 07:50:30