SQL SERVER:select 字符串拼接问题

本文介绍在SQL Server中如何将多条记录的特定字段合并为一个字符串的方法,包括使用函数、游标、临时表等不同场景下的实现技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、问题

select UserID,LastName,FirstName,UserName From SYSUser

UserID LastName FirstName UserName
------------------------------------------------------
1      A        B        C
2      A1      B1        C1
3      A2      B2        C2

  我想把这个select出来的纪录集拼接成一个字符串。应该怎么实现?例如:

strUserName=C,c2,c2

 

  二、解决

  SQL code问题描述:无论是在sql 2000,还是在 SQL 2005 中,都没有提供字符串的聚合函数,所以,当我们在处理下列要求时,会比较麻烦:

  有表tb, 如下:

id    value
----- ------
1     aa
1     bb
2     aaa
2     bbb
2     ccc

  需要得到结果:

id     values
------ -----------
1      aa,bb
2      aaa,bbb,ccc

  即, group by id, 求 value 的和(字符串相加)

  方法1、 旧的解决方法

-- 1. 创建处理函数
CREATE FUNCTION dbo.f_str(@id int)
RETURNS varchar(8000)
AS
BEGIN
    DECLARE @r varchar(8000)
    SET @r = ''
    SELECT @r = @r + ',' + value
    FROM tb
    WHERE id=@id
    RETURN STUFF(@r, 1, 1, '')
END
GO
-- 调用函数

SELECt id, values=dbo.f_str(id)
FROM tb
GROUP BY id

 

  方法2、新的解决方法

  1、示例数据

DECLARE @t TABLE(id int, value varchar(10))
INSERT @t SELECT 1, 'aa'
UNION ALL SELECT 1, 'bb'
UNION ALL SELECT 2, 'aaa'
UNION ALL SELECT 2, 'bbb'
UNION ALL SELECT 2, 'ccc'

  2、查询处理

SELECT * FROM(
    SELECT DISTINCT id
    FROM @t
)A
OUTER APPLY(
    SELECT
        [values]= STUFF(REPLACE(REPLACE(
            (
                SELECT value FROM @t N
                WHERE id = A.id
                FOR XML AUTO
            ), '<N value="', ','), '"/>', ''), 1, 1, '')
)N

  3、结果

id          values
----------- ----------------
1           aa,bb
2           aaa,bbb,ccc
(2 行受影响)


  三、各种字符串分函数

--3.3.1 使用游标法进行字符串合并处理的示例。
--处理的数据
CREATE TABLE tb(col1 varchar(10),col2 int)
INSERT tb SELECT 'a',1
UNION ALL SELECT 'a',2
UNION ALL SELECT 'b',1
UNION ALL SELECT 'b',2
UNION ALL SELECT 'b',3

--合并处理
--定义结果集表变量
DECLARE @t TABLE(col1 varchar(10),col2 varchar(100))

--定义游标并进行合并处理
DECLARE tb CURSOR LOCAL
FOR
SELECT col1,col2 FROM tb ORDER BY col1,col2
DECLARE @col1_old varchar(10),@col1 varchar(10),@col2 int,@s varchar(100)
OPEN tb
FETCH tb INTO @col1,@col2
SELECT @col1_old=@col1,@s=''
WHILE @@FETCH_STATUS=0
BEGIN
    IF @col1=@col1_old
        SELECT @s=@s+','+CAST(@col2 as varchar)
    ELSE
    BEGIN
        INSERT @t VALUES(@col1_old,STUFF(@s,1,1,''))
        SELECT @s=','+CAST(@col2 as varchar),@col1_old=@col1
    END
    FETCH tb INTO @col1,@col2
END
INSERT @t VALUES(@col1_old,STUFF(@s,1,1,''))
CLOSE tb
DEALLOCATE tb
--显示结果并删除测试数据
SELECT * FROM @t
DROP TABLE tb
/*--结果
col1       col2
---------- -----------
a          1,2
b          1,2,3
--*/
GO


/*==============================================*/


--3.3.2 使用用户定义函数,配合SELECT处理完成字符串合并处理的示例
--处理的数据
CREATE TABLE tb(col1 varchar(10),col2 int)
INSERT tb SELECT 'a',1
UNION ALL SELECT 'a',2
UNION ALL SELECT 'b',1
UNION ALL SELECT 'b',2
UNION ALL SELECT 'b',3
GO

--合并处理函数
CREATE FUNCTION dbo.f_str(@col1 varchar(10))
RETURNS varchar(100)
AS
BEGIN
    DECLARE @re varchar(100)
    SET @re=''
    SELECT @re=@re+','+CAST(col2 as varchar)
    FROM tb
    WHERE col1=@col1
    RETURN(STUFF(@re,1,1,''))
END
GO

--调用函数
SELECT col1,col2=dbo.f_str(col1) FROM tb GROUP BY col1
--删除测试
DROP TABLE tb
DROP FUNCTION f_str
/*--结果
col1       col2
---------- -----------
a          1,2
b          1,2,3
--*/
GO

/*==============================================*/


--3.3.3 使用临时表实现字符串合并处理的示例
--处理的数据
CREATE TABLE tb(col1 varchar(10),col2 int)
INSERT tb SELECT 'a',1
UNION ALL SELECT 'a',2
UNION ALL SELECT 'b',1
UNION ALL SELECT 'b',2
UNION ALL SELECT 'b',3

--合并处理
SELECT col1,col2=CAST(col2 as varchar(100))
INTO #t FROM tb
ORDER BY col1,col2
DECLARE @col1 varchar(10),@col2 varchar(100)
UPDATE #t SET
    @col2=CASE WHEN @col1=col1 THEN @col2+','+col2 ELSE col2 END,
    @col1=col1,
    col2=@col2
SELECT * FROM #t
/*--更新处理后的临时表
col1       col2
---------- -------------
a          1
a          1,2
b          1
b          1,2
b          1,2,3
--*/
--得到最终结果
SELECT col1,col2=MAX(col2) FROM #t GROUP BY col1
/*--结果
col1       col2
---------- -----------
a          1,2
b          1,2,3
--*/
--删除测试
DROP TABLE tb,#t
GO


/*==============================================*/

--3.3.4.1 每组 <=2 条记录的合并
--处理的数据
CREATE TABLE tb(col1 varchar(10),col2 int)
INSERT tb SELECT 'a',1
UNION ALL SELECT 'a',2
UNION ALL SELECT 'b',1
UNION ALL SELECT 'b',2
UNION ALL SELECT 'c',3

--合并处理
SELECT col1,
    col2=CAST(MIN(col2) as varchar)
        +CASE
            WHEN COUNT(*)=1 THEN ''
            ELSE ','+CAST(MAX(col2) as varchar)
        END
FROM tb
GROUP BY col1
DROP TABLE tb
/*--结果
col1       col2     
---------- ----------
a          1,2
b          1,2
c          3
--*/

--3.3.4.2 每组 <=3 条记录的合并
--处理的数据
CREATE TABLE tb(col1 varchar(10),col2 int)
INSERT tb SELECT 'a',1
UNION ALL SELECT 'a',2
UNION ALL SELECT 'b',1
UNION ALL SELECT 'b',2
UNION ALL SELECT 'b',3
UNION ALL SELECT 'c',3

--合并处理
SELECT col1,
    col2=CAST(MIN(col2) as varchar)
        +CASE
            WHEN COUNT(*)=3 THEN ','
                +CAST((SELECT col2 FROM tb WHERE col1=a.col1 AND col2 NOT IN(MAX(a.col2),MIN(a.col2))) as varchar)
            ELSE ''
        END
        +CASE
            WHEN COUNT(*)>=2 THEN ','+CAST(MAX(col2) as varchar)
            ELSE ''
        END
FROM tb a
GROUP BY col1
DROP TABLE tb
/*--结果
col1       col2
---------- ------------
a          1,2
b          1,2,3
c          3
--*/
GO
if not object_id('A') is null
    drop table A
Go
Create table A([id] int,[cname] nvarchar(2))
Insert A
select 1,N'张三' union all
select 2,N'李四' union all
select 3,N'王五' union all
select 4,N'蔡六'
Go
--> -->

if not object_id('B') is null
    drop table B
Go
Create table B([id] int,[cname] nvarchar(5))
Insert B
select 1,N'1,2,3' union all
select 2,N'3,4'
Go
create function F_str(@cname nvarchar(100))
returns nvarchar(100)
as
begin
select @cname=replace(@cname,ID,[cname]) from A where patindex('%,'+rtrim(ID)+',%',','+@cname+',')>0
return @cname
end
go
select [id],dbo.F_str([cname])[cname] from B

id          cname
----------- ----------------------------------------------------------------------------------------------------
1           张三,李四,王五
2           王五,蔡六

    .
[华 软 网]
编程论坛 2 个网友回答:

 

SQL code
DECLARE @STR VARCHAR(8000)
SELECT @STR=ISNULL(@STR+',','')+USERNAME FROM TB
SELECT @STR
    .
[华 软 网]
编程论坛 3 个网友回答:
SQL code
DECLARE @TB TABLE([UserID] INT, [LastName] VARCHAR(2), [FirstName] VARCHAR(2), [UserName] VARCHAR(2))
INSERT @TB
SELECT 1, 'A', 'B', 'C' UNION ALL
SELECT 2, 'A1', 'B1', 'C1' UNION ALL
SELECT 3, 'A2', 'B2', 'C2'

DECLARE @STR VARCHAR(8000)
SET @STR=''
SELECT @STR=@STR+','+[UserName]
FROM @TB

SELECT STUFF(@STR,1,1,'')
/*
C,C1,C2
*/
    .
[华 软 网]
编程论坛 4 个网友回答:
SQL code
/*
标题:按某字段合并字符串之一(简单合并)
作者:爱新觉罗.毓华(十八年风雨,守得冰山雪莲花开)
时间:2008-11-06
地点:广东深圳

描述:将如下形式的数据按id字段合并value字段。
id    value
----- ------
1     aa
1     bb
2     aaa
2     bbb
2     ccc
需要得到结果:
id     value
------ -----------
1      aa,bb
2      aaa,bbb,ccc
即:group by id, 求 value 的和(字符串相加)
*/
--1、sql2000中只能用自定义的函数解决
create table tb(id int, value varchar(10))
insert into tb values(1, 'aa')
insert into tb values(1, 'bb')
insert into tb values(2, 'aaa')
insert into tb values(2, 'bbb')
insert into tb values(2, 'ccc')
go

create function dbo.f_str(@id int) returns varchar(100)
as
begin
    declare @str varchar(1000)
    set @str = ''
    select @str = @str + ',' + cast(value as varchar) from tb where id = @id
    set @str = right(@str , len(@str) - 1)
    return @str
end
go

--调用函数
select id , value = dbo.f_str(id) from tb group by id

drop function dbo.f_str
drop table tb


--2、SQL2005中的方法
create table tb(id int, value varchar(10))
insert into tb values(1, 'aa')
insert into tb values(1, 'bb')
insert into tb values(2, 'aaa')
insert into tb values(2, 'bbb')
insert into tb values(2, 'ccc')
go

select id, [value] = stuff((select ',' + [value] from tb t where id = tb.id for XML path('')) , 1 , 1 , '')
from tb
group by id

drop table tb


--3、使用游标合并数据
create table tb(id int, value varchar(10))
insert into tb values(1, 'aa')
insert into tb values(1, 'bb')
insert into tb values(2, 'aaa')
insert into tb values(2, 'bbb')
insert into tb values(2, 'ccc')
go
declare @t table(id int,value varchar(100))--定义结果集表变量
--定义游标并进行合并处理
declare my_cursor cursor local for
select id , value from tb
declare @id_old int , @id int , @value varchar(10) , @s varchar(100)
open my_cursor
fetch my_cursor into @id , @value
select @id_old = @id , @s=''
while @@FETCH_STATUS = 0
begin
    if @id = @id_old
       select @s = @s + ',' + cast(@value as varchar)
    else
      begin
        insert @t values(@id_old , stuff(@s,1,1,''))
        select @s = ',' + cast(@value as varchar) , @id_old = @id
      end
    fetch my_cursor into @id , @value
END
insert @t values(@id_old , stuff(@s,1,1,''))
close my_cursor
deallocate my_cursor

select * from @t
drop table tb

本文来自优快云博客,转载请标明出处:http://blog.youkuaiyun.com/htl258/archive/2009/03/03/3948758.ASPx

### 如何在 SQL Server拼接三个字符串SQL Server 中,可以通过多种方式实现字符串拼接操作。以下是几种常见的方法: #### 方法一:使用加号 (`+`) 运算符 SQL Server 支持通过 `+` 符号直接连接两个或多个字符串[^4]。当需要拼接三个字符串时,只需简单地将它们依次相加即可。 ```sql DECLARE @str1 NVARCHAR(50) = 'Hello'; DECLARE @str2 NVARCHAR(50) = ' '; DECLARE @str3 NVARCHAR(50) = 'World'; SELECT @str1 + @str2 + @str3 AS Result; ``` 需要注意的是,在这种情况下,如果任意一个参与运算的表达式为 NULL,则整个结果也会返回 NULL。因此,建议在实际应用中结合 ISNULL 或 COALESCE 函数处理可能存在的 NULL 值。 #### 方法二:使用 CONCAT 函数 CONCAT 是一种更灵活的方式用于字符串拼接,它能够自动忽略 NULL 值并将其视为空字符串。对于拼接三个字符串的情况,可以直接调用该函数如下所示: ```sql DECLARE @str1 NVARCHAR(50) = 'Hello'; DECLARE @str2 NVARCHAR(50) = NULL; -- 测试 NULL 的情况 DECLARE @str3 NVARCHAR(50) = 'World'; SELECT CONCAT(@str1, @str2, @str3) AS Result; ``` 此方法的优势在于无需额外考虑 NULL 处理逻辑,简化了代码复杂度。 #### 方法三:利用 STRING_AGG 函数(适用于特定场景) 虽然 STRING_AGG 主要设计用来聚合多行数据成单一字符串,但在某些特殊需求下也可以间接完成类似功能[^3]。不过这种方法通常不推荐作为常规手段来解决简单的三字符串拼接问题。 --- ### 总结 综上所述,在日常开发过程中最常用到的就是前两种基本技术——即基于 "+" 的手动组合以及借助于系统提供给我们的便捷工具 CONCATE() 来达成目标。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值