adi*_*iti 7 sql t-sql sql-server sql-server-2005 common-table-expression
我有一张看起来像的桌子
ID Layout
1 hello,world,welcome,to,tsql
2 welcome,to,stackoverflow
Run Code Online (Sandbox Code Playgroud)
期望的输出应该是
Id Splitdata
1 hello
1 world
1 welcome
1 to
1 tsql
2 welcome
2 to
2 stackoverflow
Run Code Online (Sandbox Code Playgroud)
我已通过以下查询完成此操作
Declare @t TABLE(
ID INT IDENTITY PRIMARY KEY,
Layout VARCHAR(MAX)
)
INSERT INTO @t(Layout)
SELECT 'hello,world,welcome,to,tsql' union all
SELECT 'welcome,to,stackoverflow'
--SELECT * FROM @t
;With cte AS(
select F1.id
,O.splitdata
from
(
select *,
cast('<X>'+replace(F.Layout,',','</X><X>')+'</X>' as XML) as xmlfilter
from @t F
)F1
cross apply
(
select fdata.D.value('.','varchar(MAX)') as splitdata
from f1.xmlfilter.nodes('X') as fdata(D)) O
)
select * from cte
Run Code Online (Sandbox Code Playgroud)
但表现明智,这是非常糟糕的.我正在寻找一个更有效的查询,但只使用CTE.
请帮忙
谢谢
KM.*_*KM. 11
你似乎已经开始使用CTE了,所以试试这个:
DECLARE @YourTable table (RowID int, Layout varchar(200))
INSERT @YourTable VALUES (1,'hello,world,welcome,to,tsql')
INSERT @YourTable VALUES (2,'welcome,to,stackoverflow')
;WITH SplitSting AS
(
SELECT
RowID,LEFT(Layout,CHARINDEX(',',Layout)-1) AS Part
,RIGHT(Layout,LEN(Layout)-CHARINDEX(',',Layout)) AS Remainder
FROM @YourTable
WHERE Layout IS NOT NULL AND CHARINDEX(',',Layout)>0
UNION ALL
SELECT
RowID,LEFT(Remainder,CHARINDEX(',',Remainder)-1)
,RIGHT(Remainder,LEN(Remainder)-CHARINDEX(',',Remainder))
FROM SplitSting
WHERE Remainder IS NOT NULL AND CHARINDEX(',',Remainder)>0
UNION ALL
SELECT
RowID,Remainder,null
FROM SplitSting
WHERE Remainder IS NOT NULL AND CHARINDEX(',',Remainder)=0
)
SELECT * FROM SplitSting ORDER BY RowID
Run Code Online (Sandbox Code Playgroud)
OUTPUT:
RowID Part
----------- -----------------------
1 hello
1 world
1 welcome
1 to
1 tsql
2 welcome
2 to
2 stackoverflow
(8 row(s) affected)
Run Code Online (Sandbox Code Playgroud)
这是一篇关于在SQL Server中拆分字符串的优秀文章:"SQL Server 2005及更高版本中的数组和列表,当表值参数不能删除它"时,Erland Sommarskog
编辑这里的另一个版本(但你需要一个数字表)返回与上面相同的结果:
;WITH SplitValues AS
(
SELECT
RowID,ListValue
FROM (SELECT
RowID, LTRIM(RTRIM(SUBSTRING(List2, number+1, CHARINDEX(',', List2, number+1)-number - 1))) AS ListValue
FROM (
SELECT RowID, ',' + Layout + ',' AS List2
FROM @YourTable
) AS dt
INNER JOIN Numbers n ON n.Number < LEN(dt.List2)
WHERE SUBSTRING(List2, number, 1) = ','
) dt2
WHERE ListValue IS NOT NULL AND ListValue!=''
)
SELECT * FROM SplitValues
Run Code Online (Sandbox Code Playgroud)
在这里查看数字表:创建和填充数字表的最佳方法是什么?
| 归档时间: |
|
| 查看次数: |
20158 次 |
| 最近记录: |