暴难的字符串拼接问题(不可以用临时表 及 游标)

zcwmxn 2007-04-04 11:26:25
现在有表:

FieldValue ConcatenationOrder
-------------------------
TH NULL
LF NULL
1N4148-TAP NULL
1 1
VF 1
0.3 2
A 2
80 4
VBR 4
DO35 NULL

****************************************************************
需要拼接字符串结果如下:
------------------------------------------------
TH,LF,1N4148-TAP,1VF,0.3A,80VBR,DO35

****************************************************************
规则:
如果ConcatenationOrder字段为NULL,用逗号(,)格开,如果不为null,字符直接连接,但不同的ConcatenationOrder字段,其FieldValue需用逗号(,)格开。
不可以用临时表,不可以用游标。其他应该都可以使用。

****************************************************************
现在有一个比较接近的语句可以参考,或者推翻重新写也可以。

declare @str varchar(8000)
set @str=''
select @str=@str+',' +cast(FieldValue as varchar) from
(
select * from testtable
) x
set @str=right(@str,len(@str)-1)
select @str

****************************************************************
表结构数据提供:
if exists (select * from dbo.sysobjects where id = object_id(N'[TestTable]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [TestTable]
GO
create table TestTable(
FieldValue varchar(80),
ConcatenationOrder int
)
GO

insert into TestTable
select 'TH',NULL
union select 'LF', NULL
union select '1N4148-TAP',NULL
union select '1',1
union select 'VF',1
union select '0.3',2
union select 'A',2
union select '80',4
union select 'VBR',4
union select 'DO35',NULL
Go

select * from testtable
GO
...全文
670 39 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
39 条回复
切换为时间正序
请发表友善的回复…
发表回复
zcwmxn 2007-04-06
  • 打赏
  • 举报
回复
不错,不错
hillhx 2007-04-06
  • 打赏
  • 举报
回复
不可以用临时表,不可以用游标。其他应该都可以使用?

如果FieldValue 是主键,可以利用TOP 1来循环,否则想实现你说的,就不可能不用游标或临时表
fcuandy 2007-04-06
  • 打赏
  • 举报
回复
DECLARE @str VARCHAR(1000)
SET @str=''
SELECT @str=@str + FieldValue +ISNULL(STUFF(RTRIM(NULLIF(ISNUMERIC(FieldValue),1))+',',1,1,''),'') FROM testTable
SELECT @str=LEFT(@str,LEN(@str)-1)
SELECT @str
honkerhero 2007-04-05
  • 打赏
  • 举报
回复
好办法,长见识了
xiaoku 2007-04-05
  • 打赏
  • 举报
回复
厉害!
敬以直内 2007-04-05
  • 打赏
  • 举报
回复
佩服鱼
hyc_music1981 2007-04-05
  • 打赏
  • 举报
回复
好厉害的鱼,佩服!
敬以直内 2007-04-05
  • 打赏
  • 举报
回复
--再改下

DECLARE @SQL VARCHAR(8000)
DECLARE @STA INT
SELECT @SQL=''
select @SQL=CASE WHEN ConcatenationOrder IS NOT NULL THEN
CASE WHEN @STA = ConcatenationOrder THEN @SQL+FieldValue
ELSE @SQL+','+ FieldValue END
ELSE @SQL+','+ FieldValue
END,@STA=ConcatenationOrder
from TestTable

SELECT RIGHT(@SQL,LEN(@SQL)-1)
敬以直内 2007-04-05
  • 打赏
  • 举报
回复

错了,可以不用自增列,把自增列去掉,结果一样
敬以直内 2007-04-05
  • 打赏
  • 举报
回复
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[TestTable]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [dbo].[TestTable]
GO

CREATE TABLE [dbo].[TestTable] (
[ID] [int] IDENTITY (1, 1) NOT NULL ,
[FieldValue] [varchar] (80) COLLATE Chinese_PRC_CI_AS NULL ,
[ConcatenationOrder] [int] NULL
) ON [PRIMARY]
GO


insert into TestTable
select 'TH',NULL
union ALL select 'LF', NULL
union ALL select '1N4148-TAP',NULL
union ALL select '1',1
union ALL select 'VF',1
union ALL select '0.3',2
union ALL select 'A',2
union ALL select '80',4
union ALL select 'VBR',4
union ALL select 'DO35',NULL
Go

select * from testtable
GO
DECLARE @SQL VARCHAR(8000)
DECLARE @STA INT
SELECT @SQL=''
select @SQL=CASE WHEN ConcatenationOrder IS NOT NULL
AND @STA = ConcatenationOrder THEN @SQL+FieldValue
WHEN ConcatenationOrder IS NOT NULL
AND @STA <> ConcatenationOrder
THEN @SQL+','+ FieldValue
ELSE @SQL+','+ FieldValue
END,@STA=ConcatenationOrder
from TestTable
SELECT RIGHT(@SQL,LEN(@SQL)-1)

--结果
--增加了个自增列,union会排序,改成union ALL
--TH,LF,1N4148-TAP,1VF,0.3A,80VBR,DO35
zjcxc 2007-04-04
  • 打赏
  • 举报
回复

SELECT
FieldValue = REPLACE(re.value('(/r)[1]', 'nvarchar(max)'), N' ,', N'')
FROM(
SELECT re = (
SELECT *
FROM(
SELECT FieldValue
FROM testtable
WHERE ConcatenationOrder IS NULL
UNION ALL
SELECT
FieldValue = REPLACE(B.FieldValue.value('(/r)[1]', 'nvarchar(max)'), N' ', N'')
FROM(
SELECT DISTINCT
ConcatenationOrder
FROM testtable
WHERE ConcatenationOrder IS NOT NULL
)A
CROSS APPLY(
SELECT FieldValue =(
SELECT v = FieldValue
FROM testtable t
WHERE ConcatenationOrder = A.ConcatenationOrder
FOR XML AUTO, TYPE
).query('<r>{for $i in /t/@v return(string($i))}</r>')

)B
)AA
FOR XML AUTO, TYPE
).query('<r>{for $i in /AA/@FieldValue return(concat(",",string($i)))}</r>')
)AAA
CathySun118 2007-04-04
  • 打赏
  • 举报
回复
难啊,期待高人
zcwmxn 2007-04-04
  • 打赏
  • 举报
回复
多谢大家关注,居然顶到了“技术热贴”。呵呵,出乎意料!

【SQL Server】 暴难的字符串拼接问题(不可以用临时表 及 游标) (人气:214)

虽然问题已经解决。为了答谢大家的关注,再放一天,明日一早揭帖。

再次感谢paoluo(一天到晚游泳的鱼),以及其他对此问题提出自己宝贵意见的同志们。
dawugui 2007-04-04
  • 打赏
  • 举报
回复
1 1

这行去哪里了?
xiaoku 2007-04-04
  • 打赏
  • 举报
回复
lz 好人...写了测试数据.
hrb2008 2007-04-04
  • 打赏
  • 举报
回复
鱿鱼的是最简的:)
paoluo 2007-04-04
  • 打赏
  • 举报
回复
收回我之前說的話, :)。

現在才想到這個方法。

paoluo 2007-04-04
  • 打赏
  • 举报
回复
--笨死,到現在才想到這個方法,應該是最簡單的了吧。

create table TestTable(
FieldValue varchar(80),
ConcatenationOrder int
)
GO

insert into TestTable
select 'TH',NULL
union All select 'LF', NULL
union All select '1N4148-TAP',NULL
union All select '1',1
union All select 'VF',1
union All select '0.3',2
union All select 'A',2
union All select '80',4
union All select 'VBR',4
union All select 'DO35',NULL
go
declare @s varchar(200), @ConcatenationOrder int
Select @S = ''
Select
@S = @S + (Case When ConcatenationOrder = @ConcatenationOrder Then '' Else ',' End) + FieldValue, @ConcatenationOrder = ConcatenationOrder
From
TestTable

Select @S = Stuff(@S, 1, 1, '')
Select @S As FieldValue
GO
Drop Table TestTable
--Result
/*
FieldValue
TH,LF,1N4148-TAP,1VF,0.3A,80VBR,DO35
*/
hrb2008 2007-04-04
  • 打赏
  • 举报
回复
变量弄个:)

create table a
(
FieldValue varchar(20),
ConcatenationOrder int
)
go
insert into a
select 'TH',null union all
select 'LF',null union all
select '1N4148-TAP',null union all
select '1',1 union all
select 'VF',1 union all
select '0.3',2 union all
select 'a',2 union all
select '80',4 union all
select 'VBR',4 union all
select 'DO35',null
go
declare @s varchar(200),@str varchar(200),@l varchar(50),@r varchar(50),@lr varchar(50),@rr varchar(50)
set @s=''
set @str=''
select @s=@s+FieldValue+case when ConcatenationOrder is null then ',' else '|'+cast(ConcatenationOrder as varchar)+'^' end from a
while charindex('^',@s)>0
begin
set @l=left (@s,charindex('^',@s))
set @r=right(@s,len(@s)-len(@l))
set @r=left(@r,charindex('^',@r))
set @lr=reverse(@l)
set @rr=reverse(@r)
--print @l +'=='+@r
if left(@lr,charindex('|',@lr ))=left(@rr,charindex('|',@rr ))
set @str=@str+left(@l,charindex('|',@l)-1)
else
set @str=@str+left(@l,charindex('|',@l))
set @s=stuff(@s,1,charindex('^',@s),'')
end
if right(@s,1)=','
set @str=@str+@s
select left(replace(@str,'|',','),len(@str)-1)
--结果
TH,LF,1N4148-TAP,1VF,0.3a,80VBR,DO35

(1 行受影响)
lxsfg 2007-04-04
  • 打赏
  • 举报
回复
拿C#写一个存储过程就可以,不用搞得这么复杂
加载更多回复(19)

22,300

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧