'12263,2,3,18321,2,1,19323,3,2,23152,5,4,27354,4,5'
이런형태의 , 로만 구분되어져 있는 특정 스트링을 파라미터로 넘겨받아
function을 이용하여
Key 1 | Key 2 | Key 3 |
12263 | 2 | 3 |
18321 | 2 | 1 |
19323 | 3 | 2 |
23152 | 5 | 4 |
27354 | 4 | 5 |
이런형태로 만들어서 쓰고 있습니다. function에서는 위와 같은 테이블을 리턴해서 쓰고 있는데
문제는 현재 사용중인 function이 CPU를 많이 사용하여 개선의 필요성을 느끼고
예전에 썼던 XML쿼리를 이용하여
Key |
12263 |
2 |
3 |
18231 |
2 |
1 |
23152 |
... |
이렇게 1개의 열로는 만들었는데 위의 테이블대로 만들기 위해선
1번째값은 1번째컬럼, 2번째값은 2번째컬럼, 3번째값은 3번째컬럼,
4번째값은 1번째컬럼, 5번째값은 2번째컬럼, 6번째값은 3번째컬럼 ....
이렇게 만들어야 할텐데 도저히 쿼리를 어떻게 만들어야할지 모르겠어서 도움 요청드립니다.
현재는 서버가 던져주는 스트링 값의 형태를 바꾸기는 쉽지 않은 상황입니다..ㅜㅜ
Comment 5
-
처리짱
2016.10.21 14:51
-
라퓨
2016.10.21 14:55
현재는 클라이언트에서 가공할수 있는 상황이 아니고 DB에서 처리를 해야하는 상황입니다..ㅜㅜ
column1
1
2
3
4
5
6
이런 형태의 결과값을 DB에서 다시한번 SELECT 문을 이용하여
Column1 Column2 Column3
1 2 3
4 5 6
위와같이 SELECT 할수있는 방법이 있을지 궁금합니다.
-
항해자™
2016.10.21 14:56
혹시 어플 로직을 변경할 수 있다면, UDT로 데이터를 받는게 가장 좋을 것 같구요,,,
그게 아니라면 스트링 파싱을 해야 하는데, 젤 빠른건 clr 이고, 차선책으로 쓸만한 것은 xml 파싱입니다.
xml 파싱을 사용한다면, 아래와 같은 방식으로 해 볼수 있겠네요,,
create function dbo.fnTbl2NString
( @pString xml
) returns table
as
return (
select row_number() over(order by (select 1)) as cRows
, col.value('@n','nvarchar(1000)') as cValue
from @pString.nodes('/x') as a (col)
)
go
declare @vString varchar(max) = '박정아^010-1234-5678|최승현^010-2345-6789|김수영^010-3456-7890|이승우^010-5555-2222|문지현^010-4444-8888'
declare @vXML xml = convert(xml,N'<x n="'+ replace(@vString,'|','"/><x n="') +'"/>')
select max(case b.cRows when 1 then b.cValue end) as cName
, max(case b.cRows when 2 then b.cValue end) as cTels
from dbo.fnTbl2NString(@vXML) as a
cross apply (
select *
from dbo.fnTbl2NString(convert(xml,'<x n="'+ replace(a.cValue,'^','"/><x n="') +'"/>'))
) as b
group by a.cRows
go
-
항해자™
2016.10.21 15:54
위에 등록한 함수를 이용해서 만들어 봤습니다,,declare @vString varchar(1000) = '12263,2,3,18321,2,1,19323,3,2,23152,5,4,27354,4,5'; declare @vXML xml = convert(xml,N'<x n="'+ replace(@vString,',','"/><x n="') +'"/>') ;with cteSample as ( select cRows , cRows % 3 as cDiv , cValue from dbo.fnTbl2NString(@vXML) ) select (cRows - 1) / 3 as cIdx , max(case cDiv when 1 then cValue end) as col1 , max(case cDiv when 2 then cValue end) as col2 , max(case cDiv when 0 then cValue end) as col3 from cteSample as a group by (cRows - 1) / 3 go
-
라퓨
2016.10.27 16:10
질문글 올린 이후로 너무 바빠서 확인도 못했는데 명쾌한 답변을 주셔서 너무 감사드립니다 ㅠㅠ
질문의 내용을 잘 이해 못하겠습니다만..
함수를 이용해서 CPU가 비용이 높다면은 그부분을 클라이언트로 보내서
클라이언트에서 다시 가공을 하셔도 될텐데요..
저 같은 경우 ORDER BY 같은 구문때문에 CPU를 많이 쓰게 되는 쿼리들은 다 클라이언트에서 재정렬을 시키거든요..