04. 문자열 병합 및 띄어쓰기 매듭

27040 단어 문자열
하나.문자 결합
if OBJECT_ID('ConcatStr') is not null
drop table ConcatStr
GO
create table ConcatStr
(
ID int,
Code varchar(10)
)
GO
insert into ConcatStr
select 1,'XXX' union all
select 1,'YYY' union all
select 2,'PPP' union all
select 2,'QQQ'

이러한 결과를 얻으려면:
ID
Code
1
XXX,YYY
2
PPP,QQQ
1. 커서로
declare @t table(ID int, Code varchar(1000))
declare @id int
declare c cursor for 
select distinct ID from ConcatStr
open c
fetch next from c into @id
while @@fetch_status=0
begin
declare @str varchar(max)
set @str = ''
select @str = @str + ',' + Code from ConcatStr where ID = @id
insert into @t(ID, Code)
select @id,stuff(@str,1,1,'')
fetch next from c into @id
end
close c
deallocate c
select * from @t

 2. 사용자 정의 함수 사용하기
커서의 방법과 유사하지만, 하나하나 취한 동작을 함수에 봉인할 뿐이다.(1) 함수 방법 1
if OBJECT_ID('f_concat_str') is not null
drop function f_concat_str
GO
create function f_concat_str(@id int)
returns nvarchar(4000)
as
begin
declare @s nvarchar(4000)
set @s=''
select @s = @s+',' + Code from ConcatStr where ID = @id
return (stuff(@s,1,1,''))
--return (right(@s,len(@s)-1)) 
End

(2) 함수 방법 2는 함수 1을 간소화하는 것이다
if OBJECT_ID('f_concat_str') is not null
drop function f_concat_str
GO
create function f_concat_str(@id int)
returns nvarchar(4000)
as
begin
declare @s nvarchar(4000)
--set @s=''
--select @s = case when @s = '' then Code else @s + ',' + Code end
--from ConcatStr where ID = @id
select @s = isnull(@s + ',','') + Code from ConcatStr where ID = @id
return @s
end

함수 1 또는 함수 2 호출
--select ID,dbo.f_concat_str(ID) as Code
--from ConcatStr 
--group by ID
Select distinct ID, Code = dbo.f_concat_str(ID) 
from ConcatStr

 3. 정적 행렬을 이용하여 쓰기 변환하기
그룹의 줄마다 번호를 만들고, 행렬이 바뀐 후에 열을 연결합니다. 번호가 몇 개인지는 그룹마다 COUNT (1) 의 값에 달려 있습니다.
SELECT ID,
       MAX(CASE WHEN num = 1 THEN Code ELSE '' END)
     + MAX(CASE WHEN num = 2 THEN ',' + Code ELSE '' END) AS Code
FROM (SELECT ID, Code,
      (SELECT COUNT(*)
         FROM dbo.ConcatStr AS t2
        WHERE t2.ID = t1.ID
          AND t2.Code <= t1.Code) AS num
FROM dbo.ConcatStr AS t1) AS t
GROUP BY ID;

 4. FOR XML 자구를 사용한 작업
(1) FOR XML AUTOSQL Server 2000에 이 자구가 있지만 OUTER APPLY는 SQL Server 2005의 문법이다.일반적으로 이런 쓰기 효율은 함수를 사용하는 것보다 빠르지 않다.
SELECT * FROM(SELECT DISTINCT ID FROM ConcatStr)A OUTER APPLY(SELECT Code= STUFF(REPLACE(REPLACE((
SELECT Code FROM ConcatStr N WHERE ID = A.ID FOR XML AUTO), '<N Code="', ','), '"/>', ''), 1, 1, ''))N

 (2) FOR XML PATH
SQL Server 2005의 새로운 구문
SELECT ID,
STUFF((SELECT ',' + Code
FROM dbo.ConcatStr AS t2
WHERE t2.ID = t1.ID
ORDER BY ID
FOR XML PATH('')), 1, 1, '') AS Code
FROM dbo.ConcatStr AS t1
GROUP BY ID;

 
둘.문자 분할
if not object_id('SplitStr') is null
drop table SplitStr
Go
create table SplitStr
(
Col1 int,
Col2 nvarchar(10)
)
insert SplitStr
select 1,N'a,b,c' union all
select 2,N'd,e' union all
select 3,N'f'
Go

이러한 결과를 얻으려면:
Col1
Code
1
a
1
b
1
c
2
d
2
e
3
f
1. 숫자 보조표 사용
if object_id('Tempdb..#Num') is not null
drop table #Num
GO
select top 100 ID = Identity(int,1,1) into #Num 
--   ROW_NUMBER()   
from syscolumns a,syscolumns b
GO
Select a.Col1,Col2=substring(a.Col2,b.ID,charindex(',',a.Col2+',',b.ID)-b.ID) 
from SplitStr a,#Num b
where charindex(',',','+a.Col2,b.ID)=b.ID 
--   substring(','+a.COl2,b.ID,1)=','

 2. CTE 사용
with t(Col1, p1, p2)
as
(
select Col1, charindex(',',','+col2), charindex(',',Col2+',') + 1 from SplitStr
union all
select s.Col1, t.p2, charindex(',', s.Col2+',', t.p2) + 1 
from SplitStr s join t on s.Col1 = t.Col1 where charindex(',', s.Col2+',', t.p2) > 0
)
--select * from t
select s.Col1, Col2 = substring(s.Col2+',', t.p1, t.p2-t.p1-1) 
from SplitStr s join t on s.Col1 = t.Col1 
order by s.Col1
option (maxrecursion 0)

 3. XML 사용
SELECT A.Col1, B.Code
FROM(SELECT Col1, Code = CONVERT(XML,'<root><v>' + REPLACE(Col2, ',', '</v><v>') + '</v></root>') FROM SplitStr) A
OUTER APPLY(SELECT Code = N.v.value('.', 'varchar(100)') FROM A.Code.nodes('/root/v') N(v)) B

좋은 웹페이지 즐겨찾기