根据String Split into column instead of rows中的答案,我注意到有时XmlEmail.value('/Emails[1]/email[1]','varchar(100)') AS Email1
会返回多个电子邮件,这些电子邮件由空格(\ s)或分号(;)分隔。这就是他们被输入的方式 - 查询没有错。
我试图只在那个空间之前取值,所以这就是我想出来的:
CASE CHARINDEX(' ', LTRIM(XmlEmail.value('/Emails[1]/email[1]','varchar(100)')), 1)
WHEN 0 THEN LTRIM(XmlEmail.value('/Emails[1]/email[1]','varchar(100)'))
ELSE SUBSTRING(LTRIM(XmlEmail.value('/Emails[1]/email[1]','varchar(100)')), 1, CHARINDEX(' ',LTRIM(XmlEmail.value('/Emails[1]/email[1]','varchar(100)')), 1) - 1) end as Email_1
但是,我不能这样做,因为我也有';'
的案例。
任何想法我如何实现两者?
答案 0 :(得分:2)
您仍然可以使用XML方法。唯一的诀窍是"清洁"首先是字符串。
几个月前戈登演示的这个小技巧。我无法找到原始链接,但它会将多个空格和/或分号减少到一个(展开,缩小,最后消除)。简直太棒了,只希望我能相信它。
示例强>
Declare @t table (Id INT, email_address VARCHAR(1000) , email_new VARCHAR(100));
INSERT INTO @t VALUES
(1,'a.b@wellsfargoadvisors.com', 'a.b@wellsfargoadvisors.com'),
(2,'c.b@RaymondJames.com;;;; abc@RaymondJames.com', 'abc@RaymondJames.com' ),
(3,'a.b@boa.com bbc@boa.com; hh@bankofamerica.com','a.b@boa.com' )
Select A.ID
,C.*
From @t A
Cross Apply (values (replace(replace(replace(replace(email_address,' ','<>'),';','<>'),'><',''),'<>',';'))
) B(CleanString)
Cross Apply (
Select Pos1 = ltrim(rtrim(xDim.value('/x[1]','varchar(max)')))
,Pos2 = ltrim(rtrim(xDim.value('/x[2]','varchar(max)')))
,Pos3 = ltrim(rtrim(xDim.value('/x[3]','varchar(max)')))
,Pos4 = ltrim(rtrim(xDim.value('/x[4]','varchar(max)')))
,Pos5 = ltrim(rtrim(xDim.value('/x[5]','varchar(max)')))
From (Select Cast('<x>' + replace(CleanString,';','</x><x>')+'</x>' as xml) as xDim) as A
) C
<强>返回强>
ID Pos1 Pos2 Pos3 Pos4 Pos5
1 a.b@wellsfargoadvisors.com NULL NULL NULL NULL
2 c.b@RaymondJames.com abc@RaymondJames.com NULL NULL NULL
3 a.b@boa.com bbc@boa.com hh@bankofamerica.com NULL NULL
答案 1 :(得分:1)
请改用PATINDEX
。没有数据可以测试,我不能说这会工作,但是,它可能会像:
CASE PATINDEX('%[ ;]%', LTRIM(XmlEmail.value('/Emails[1]/email[1]','varchar(100)')))
WHEN 0 THEN LTRIM(XmlEmail.value('/Emails[1]/email[1]','varchar(100)'))
ELSE SUBSTRING(LTRIM(XmlEmail.value('/Emails[1]/email[1]','varchar(100)')), 1, PATINDEX('%[ ;]%',LTRIM(XmlEmail.value('/Emails[1]/email[1]','varchar(100)'))) - 1) end as Email_1
OP说这不起作用,但它似乎对我有用:
DECLARE @Email varchar(500) = 'ab@nmfn.com ab@northwesternmutual.com';
SELECT
CASE PATINDEX('%[ ;]%', LTRIM(@Email))
WHEN 0 THEN LTRIM(@Email)
ELSE SUBSTRING(LTRIM(@Email), 1, PATINDEX('%[ ;]%',LTRIM(@Email)) - 1) end as Email_1;
返回:ab@nmfn.com
DECLARE @Email varchar(500) = 'ab@nmfn.com;ab@northwesternmutual.com';
SELECT
CASE PATINDEX('%[ ;]%', LTRIM(@Email))
WHEN 0 THEN LTRIM(@Email)
ELSE SUBSTRING(LTRIM(@Email), 1, PATINDEX('%[ ;]%',LTRIM(@Email)) - 1) end as Email_1;
还返回:ab@nmfn.com
然而,我无法针对xml运行此操作,因为(再次),我没有来自OP的那种格式的示例数据。