我想将data
列溢出到3个新列中
数据的值为Spaces OR','逗号分隔。
data
ABC, RICK SEAN, MD
MES, AEL B, MD FACC
DAN, RK, MD
OHI, NIK, MD F
KA E SYME, PA-C
ALL MUD, SIM, MD
RINE EEMAN, FNP-C
ABC, PQR DIR
必需输出:
desc last first post
ABC, RICK SEAN, MD ABC RICK SEAN MD
MES, AEL B, MD FACC MES AEL B MD FACC
DAN, RK, MD DAN RK MD
OHI, NIK, MD F OHI NIK MD F
KA E SYME, PA-C KA E SYME PA-C
ALL MUD, SIM, MD ALL MUD SIM MD
RINE EEMAN, FNP-C RINE EEMAN FNP-C
ABC, PQR DIR ABC PQR DIR
检查第一行数据列有2个逗号,最后一行只有一个逗号。
此处创建的示例http://rextester.com/BEHUP42399
select left(data, charindex(',', data) -1) from TTT
它尝试了'最后'名称列,但为'KA E SYME'提供了错误的o / p,即单个逗号记录。 如果数据有单个逗号,并且在逗号之前只有一个单词表示逗号之后有两个单词,那么结果将是。检查最后记录ABVC。
eg. ABC, PQR DIR
答案 0 :(得分:2)
您可以使用CROSS APLLY
:
SELECT N.DATA [descr],
CASE
WHEN N.last = ''
THEN LTRIM(N.first)
ELSE LTRIM(N.last)
END last,
CASE
WHEN N.last = ''
THEN SUBSTRING(LTRIM(N.post), 1, CHARINDEX(CHAR(32), LTRIM(N.post)))
ELSE LTRIM(N.first)
END first,
CASE
WHEN N.last = ''
THEN SUBSTRING(LTRIM(N.post), (CHARINDEX(' ', LTRIM(N.post))+1), LEN(LTRIM(N.post)))
ELSE LTRIM(N.post)
END post
FROM
(
SELECT D.DATA,
CASE
WHEN D.post IS NULL
THEN LEFT(D.last, CHARINDEX(' ', D.last))
ELSE D.last
END last,
CASE
WHEN d.post IS NULL
THEN SUBSTRING(D.last, (CHARINDEX(' ', D.last)+1), LEN(D.last))
ELSE d.first
END first,
CASE
WHEN D.post IS NULL
THEN d.first
ELSE d.post
END post
FROM
(
SELECT DISTINCT
DATA,
Split.a.value('/M[1]', 'NVARCHAR(MAX)') last,
Split.a.value('/M[2]', 'NVARCHAR(MAX)') first,
Split.a.value('/M[3]', 'NVARCHAR(MAX)') post
FROM
(
SELECT DATA,
CAST('<M>'+REPLACE(DATA, ',', '</M><M>')+'</M>' AS XML) AS String
FROM #TM
) A
CROSS APPLY String.nodes('/M') Split(a)
) D
) N;
期望的结果:
desc last first post
ABC, RICK SEAN, MD ABC RICK SEAN MD
MES, AEL B, MD FACC MES AEL B MD FACC
DAN, RK, MD DAN RK MD
OHI, NIK, MD F OHI NIK MD F
KA E SYME, PA-C KA E SYME PA-C
ALL MUD, SIM, MD ALL MUD SIM MD
RINE EEMAN, FNP-C RINE EEMAN FNP-C
ABC, PQR DIR ABC PQR DIR
注意:上述结果按照提供的数据。
答案 1 :(得分:1)
您可以尝试下面的查询
逻辑是当逗号小于3时,我们找到逗号的数量并为第一个出现的空格添加逗号 当字符串中没有逗号时,这也适用。
create table staging_tbl_single_row (data varchar(max))
insert into staging_tbl_single_row values
('ABC, RICK SEAN, MD')
,('MES, AEL B, MD FACC')
,('DAN, RK, MD')
,('OHI, NIK, MD F')
,('KA E SYME, PA-C')
,('ALL MUD, SIM, MD')
,('RINE EEMAN, FNP-C'),
('ABC, PQR DIR');
; with cte as
(
select
row_number() over (order by (select NULL)) as column1,
column2=
case
when
(len(data)-len(replace(data,',',''))=2)
then
data
when
(len(data)-len(replace(data,',',''))=1)
then
case --check if space is to the left of comma
when
charindex(' ',left(data, charindex(',',data)))<>0
then
stuff(data,charindex(' ',data),1,',')
else
left(data, charindex(',',data))+
stuff(
substring(data,
charindex(',',data)+1,
len(data)
),
charindex(' ',
substring(
data,
charindex(',',data)+1,
len(data)
),
2)
,1,',')
end
when
(len(data)-len(replace(data,',',''))=0)
then
stuff(
stuff(data,charindex(' ',data),1,',')
,charindex(' ',stuff(data,charindex(' ',data),1,','))
,1,',')
end,data
from
staging_tbl_single_row
)
select
last=[1],first=[2],post=[3]
from
(
select
t.column1,
split_values=SUBSTRING( t.column2, t1.N, ISNULL(NULLIF(CHARINDEX(',',t.column2,t1.N),0)-t1.N,8000)),
r= row_number() over( partition by column1 order by t1.N)
from cte t
join
(
select
t.column2,
1 as N
from cte t
UNION ALL
select
t.column2,
t1.N + 1 as N
from cte t
join
(
select
top 8000
row_number() over(order by (select NULL)) as N
from
sys.objects s1
cross join
sys.objects s2
) t1
on SUBSTRING(t.column2,t1.N,1) = ','
) t1
on t1.column2=t.column2
)a
pivot
(
max(split_values) for r in ([1],[2],[3])
)p
的 see working demo 强>
答案 2 :(得分:0)
;WITH Split_Names (data, xmlname)
AS
(
SELECT data,
CONVERT(XML,'<Names><name>'
+ REPLACE(data,',', '</name><name>') + '</name></Names>') AS xmlname
FROM TTT
)
SELECT CASE
WHEN s.post IS NULL
THEN LEFT(s.last, CHARINDEX(' ', s.last)-1)
ELSE s.last
END last,
CASE
WHEN s.post IS NULL
THEN SUBSTRING(s.last, (CHARINDEX(' ', s.last)+1), LEN(s.last))
ELSE s.first
END first,
CASE
WHEN s.post IS NULL
THEN s.first
ELSE s.post
END Post FROM
(
SELECT data,
xmlname.value('/Names[1]/name[1]','varchar(MAX)') AS Last,
xmlname.value('/Names[1]/name[2]','varchar(MAX)') AS First,
xmlname.value('/Names[1]/name[3]','varchar(MAX)') AS Post
FROM Split_Names
)s