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

SQL Server实现行数据逗号分隔拼接且最后项用AND连接

解决SQL字符串拼接:逗号分隔+最后一个用and的需求

我来帮你搞定这个字符串拼接的问题!你现在的查询把所有元素都用and连接了,想要改成前面用逗号、最后一个用and的格式,分两种情况给你方案:

情况1:使用SQL Server 2017及以上版本(推荐)

从SQL Server 2017开始支持STRING_AGG函数,这是最简洁高效的方法:

首先用STRING_AGG把所有去重后的模块名用, 拼接,然后替换最后一个逗号为and:

DECLARE @result VARCHAR(MAX)
-- 第一步:用逗号拼接所有元素
SELECT @result = STRING_AGG(module_name, ', ') WITHIN GROUP (ORDER BY module_name)
FROM (SELECT DISTINCT module_name FROM Test) T

-- 第二步:替换最后一个逗号为" and "
SELECT STUFF(@result, LEN(@result) - CHARINDEX(', ', REVERSE(@result)) + 1, 2, ' and ') AS formatted_result

原理说明:

  1. STRING_AGG会自动把所有去重后的module_name按顺序拼接成, 分隔的字符串,比如得到Table, Computer, Laptop, Chair。
  2. REVERSE(@result)反转字符串后,找到第一个, 的位置,就能算出原字符串里最后一个, 的起始位置。
  3. STUFF函数会从这个位置开始,替换掉2个字符(, 的长度)为and,最终得到你想要的格式。

如果表中只有1条数据,这个方法也能直接返回该数据,不会出现错误。

情况2:兼容SQL Server 2016及以下版本

如果你的SQL Server版本不支持STRING_AGG,可以用变量拼接+替换的方式:

DECLARE @module_name VARCHAR(MAX)
-- 先拼接成逗号分隔的字符串
SELECT @module_name = COALESCE(@module_name + ', ', '') + module_name
FROM (SELECT DISTINCT module_name FROM Test) T

-- 判断是否有多条数据,再替换最后一个逗号
SELECT CASE 
         WHEN CHARINDEX(', ', @module_name) = 0 THEN @module_name
         ELSE STUFF(@module_name, LEN(@module_name) - CHARINDEX(', ', REVERSE(@module_name)) + 1, 2, ' and ')
       END AS formatted_result

或者也可以通过统计行数,在拼接时判断是否是最后一条数据:

DECLARE @module_name VARCHAR(MAX)
DECLARE @total_count INT

-- 先统计去重后的总条数
SELECT @total_count = COUNT(DISTINCT module_name) FROM Test

-- 拼接时根据行号选择分隔符
SELECT @module_name = COALESCE(
    @module_name + CASE WHEN ROW_NUMBER() OVER (ORDER BY module_name) = @total_count THEN ' and ' ELSE ', ' END, 
    ''
) + module_name
FROM (SELECT DISTINCT module_name FROM Test) T

SELECT @module_name AS formatted_result

这个方法通过ROW_NUMBER()给每条数据编号,当是最后一条时用and,其他情况用, ,也能得到预期结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 06:56:03