使用CTE为各个字符生成行/列

时间:2011-06-20 06:06:45

标签: sql-server sql-server-2005 tsql common-table-expression

我有以下输入表

Input

ID  Row Data
1   1   a2b
1   2   p1d1
2   1   abcd

预期输出

ID  RowCol  Chars
1   a1  a
1   b1  X
1   c1  X
1   d1  b
1   a2  p
1   b2  X
1   c2  d
1   d2  X
2   a1  a
2   b1  b
2   c1  c
2   d1  d

数据列中的每个数字都将被视为许多X的数字。所以如果扩展第一个resord'a2b'  它变成了一个XXB。也就是长度为4.以列表示,它将是a,b,c和d。 因此,它位于第一行,因此输出将是

ID  RowCol  Chars
1   a1  a
1   b1  X
1   c1  X
1   d1  b

ddl在

之下
Declare @t table(ID int , Row int, Data varchar(10))
Insert into @t 
Select 1, 1,'a2b' Union All Select 1,2,'p1d1' Union All Select 2,1,'abcd'

寻找基于cte的解决方案。

提前致谢

1 个答案:

答案 0 :(得分:1)

正如我所承诺的,我今天会做出更好的解决方案。我知道你会喜欢并且最有可能使用它。

DECLARE @t TABLE(ID INT , Row INT, Data VARCHAR(10)) 
Insert INTO @t  
SELECT 1, 1,'a2b' UNION All SELECT 1,2,'p1d1' UNION All SELECT 2,1,'abcd'

;WITH cte(id, row, num, data) 
AS ( 
SELECT id, row, 1 num,CAST(data as VARCHAR(10)) data
FROM @t
UNION ALL 
SELECT ch.id, row, CH.num +1,  CAST(REPLACE(ch.data, ch.num, REPLICATE('X', ch.num)) as VARCHAR(10))
FROM cte ch
WHERE ch.num < 9 )
, cte2(id, rowcol, row, num, data, chars, LEVEL)  as
(SELECT  id, CHAR(97) + CAST(row AS CHAR) rowcol, row, num, data, SUBSTRING(data, 1, 1), 1 LEVEL
FROM cte 
where num =  9
UNION all
SELECT id, CHAR(97 + LEVEL) + CAST(row AS CHAR) rowcol, row, num, data, SUBSTRING(data, LEVEL + 1, 1), LEVEL + 1
FROM cte2 ch
where LEVEL < LEN(data)
)
SELECT ID, rowcol, chars 
FROM CTE2
ORDER BY id, data, rowcol