我正在使用sql Server数据库.我有一列包含分隔列表,我需要编写一个查询,将列表的值分成行.从浏览StackOverflow和网页的其余部分,我知道这是一个常见的问题.其实我在这里发现了一个广泛的分析:
http://www.sommarskog.se/arrays-in-sql.html
不幸的是,我在该网站和其他地方看到的每个解决方案都需要我创建一个功能.这不是我的选择 – 我缺乏使用CREATE命令所需的特权.
没有CREATE,我知道我可以使用PARSENAME函数,像这样(感谢Nathan Bedford在How do I split a string so I can access item x?.):
SELECT PARSENAME(REPLACE('Hello John Smith',' ','.'),2)
但是,PARSENAME仅适用于4个或更少的列表.因此,我的问题是:如何编写一个查询来分割多于4个项目的定界字符串,而不在数据库中创建新对象?
编辑:
感谢大家的快速答案.我可能已经省略了一些重要的信息 – 我通过ODBC连接与数据库进行交互.除了CREATE语句,似乎还有其他语句不起作用.例如,我似乎不能在一个语句中使用DECLARE来定义将在另一个语句中使用的变量.就像我可以看出的那样,我必须将所有内容都放在一个SELECT语句中(尽管WITH似乎也适用于声明普通表).不幸的是,到目前为止所建议的所有解决方案似乎都需要在SELECT语句之外的变量声明,这是不行的.请忍受我 – 我正在学习.
解决方法
使用XML的版本.
declare @S varchar(100) = 'Hello John Smith' select n.r.value('.','varchar(50)') from (select cast('<r>'+replace(@S,'</r><r>')+'</r>' as xml)) as s(XMLCol) cross apply s.XMLCol.nodes('r') as n(r)
使用表来代替
将@T替换为您正在使用的表.
-- Test table declare @T table (ID int,Col varchar(100)) insert into @T values (1,'Hello John Smith') insert into @T values (2,'xxx yyy zzz') select T.ID,n.r.value('.','varchar(50)') from @T as T cross apply (select cast('<r>'+replace(replace(Col,'&','&'),'</r><r>')+'</r>' as xml)) as S(XMLCol) cross apply S.XMLCol.nodes('r') as n(r)
拆分字符串“Hello John Smith”而不使用变量
select n.r.value('.','varchar(50)') from (select cast('<r>'+replace('Hello John Smith','</r><r>')+'</r>' as xml)) as s(XMLCol) cross apply s.XMLCol.nodes('r') as n(r)