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

基于条件的SQL Server Stuff函数使用:按ImageID分组去重拼接字段

实现SQL Server按ImageID分组去重拼接Brand和Segment

没问题,我来帮你搞定这个需求!要实现按ImageID分组,将同一组内不重复的Brand和Segment组合拼接起来,我们可以结合DISTINCT和STUFF函数来实现,要是你的SQL Server版本是2017及以上,还有更简洁的方案。

先准备示例测试数据

首先我们创建一张测试表并插入数据,模拟你提到的重复场景:

CREATE TABLE ImageDetails (
    ImageID INT,
    Brand VARCHAR(50),
    Segment VARCHAR(50)
);

INSERT INTO ImageDetails VALUES
(101, 'Nescafe', 'Coffee'),
(101, 'Nescafe', 'Coffee'), -- 完全重复的记录
(101, 'NESCAFE', 'Coffee'), -- 大小写不同的Brand
(102, 'Kitkat', 'Chocolate'),
(102, 'Kitkat', 'Chocolate'),
(102, 'Cadbury', 'Chocolate'),
(103, 'Lays', 'Snacks');

方法一:使用STUFF + FOR XML PATH(兼容所有SQL Server版本)

核心思路是先对每个ImageID下的Brand+Segment组合做去重,再用STUFF拼接结果:

-- 第一步:先提取每个ImageID下不重复的Brand-Segment组合
WITH DistinctImageData AS (
    SELECT DISTINCT
        ImageID,
        Brand + ' - ' + Segment AS BrandSegment -- 将Brand和Segment合并为单个字符串,方便去重和拼接
    FROM ImageDetails
)
-- 第二步:按ImageID分组拼接
SELECT
    ImageID,
    STUFF(
        -- 用FOR XML PATH将多行转为单个字符串
        (SELECT ', ' + BrandSegment
         FROM DistinctImageData d
         WHERE d.ImageID = main.ImageID
         FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'),
        1, 2, '' -- 去掉字符串开头多余的", "
    ) AS CombinedBrandSegments
FROM DistinctImageData main
GROUP BY ImageID;

执行后,ImageID=101会得到Nescafe - Coffee, NESCAFE - Coffee(如果需要忽略大小写去重,后面会讲处理方式),ImageID=102会得到Kitkat - Chocolate, Cadbury - Chocolate,完全符合你的需求。

方法二:使用STRING_AGG(SQL Server 2017+ 推荐)

如果你的SQL Server版本是2017或更高,STRING_AGG函数直接支持DISTINCT关键字,写法更简洁:

SELECT
    ImageID,
    STRING_AGG(DISTINCT Brand + ' - ' + Segment, ', ') AS CombinedBrandSegments
FROM ImageDetails
GROUP BY ImageID;

这个方法和上面的效果完全一致,但代码更短,维护起来更方便。

额外需求:忽略大小写去重

如果需要把Nescafe和NESCAFE视为同一个Brand,可以先统一转为小写(或大写)再去重:

WITH NormalizedData AS (
    SELECT
        ImageID,
        Brand,
        Segment,
        -- 生成标准化的去重键
        LOWER(Brand) + '|' + LOWER(Segment) AS NormalizedKey
    FROM ImageDetails
),
UniqueCombined AS (
    -- 按标准化键去重,保留原始的Brand和Segment
    SELECT
        ImageID,
        MIN(Brand) AS Brand, -- 取同一标准化组下的任意一个原始Brand(MIN/MAX都可以)
        MIN(Segment) AS Segment
    FROM NormalizedData
    GROUP BY ImageID, NormalizedKey
)
-- 最后拼接结果
SELECT
    ImageID,
    STUFF(
        (SELECT ', ' + Brand + ' - ' + Segment
         FROM UniqueCombined u
         WHERE u.ImageID = main.ImageID
         FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'),
        1, 2, ''
    ) AS CombinedBrandSegments
FROM UniqueCombined main
GROUP BY ImageID;

执行后,ImageID=101只会得到Nescafe - Coffee,大小写不同的重复项会被合并。

内容的提问来源于stack exchange,提问作者MDMalik

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 09:17:40