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
原理说明:
STRING_AGG会自动把所有去重后的module_name按顺序拼接成,分隔的字符串,比如得到Table, Computer, Laptop, Chair。REVERSE(@result)反转字符串后,找到第一个,的位置,就能算出原字符串里最后一个,的起始位置。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
相关产品推荐
相关产品推荐

