【问题标题】:Split Email with semicolon delimiter in SQL Server在 SQL Server 中使用分号分隔符拆分电子邮件
【发布时间】:2021-05-13 14:48:09
【问题描述】:

我有一列存储多个用分号分隔的电子邮件,如下所示:

|             Email            |
| -----------------------------|
| abc@y.aa; abc@z.bb           |
| pqr@y.bb; pqr@x.cc; pqr@z.dd |
| xyx@y.dd; xyx@z.pp           |

我希望使用分隔符分号拆分电子邮件并将它们存储在不同的列中。

我尝试了一些字符串命令,但没有提供合适的结果

REVERSE(PARSENAME(REPLACE(REVERSE(Email), ';', '.'), 1)) AS [Email1],
REVERSE(PARSENAME(REPLACE(REVERSE(Email), ';', '.'), 2)) AS [Email2],
REVERSE(PARSENAME(REPLACE(REVERSE(Email), ';', '.'), 3)) AS [Email3]

我们将不胜感激。

如果有更好的解决方案,欢迎在这里分享。

提前致谢!

【问题讨论】:

  • 请提供样本数据和期望的结果。另外,是否有最大数量的电子邮件?
  • 根据 SQL 的版本,有一个字符串解析函数,可以将数据解析成表格,您可以从表格结果中选择它,但正如 Linoff 所说,请提供数据和结果
  • 是的,我刚刚添加了它的 SQL Sever 2016
  • @cool_taps 然后更改损坏的功能。它从一开始就坏了,所以它迟早要修复。您现在拥有的内容根本无法被查询或索引。如果您不打算查询电子邮件值,您可以在客户端拆分,并将该字段视为黑框。

标签: sql sql-server string tsql split


【解决方案1】:

如果您有已知的或最大数量的电子邮件地址,您可以使用一点 JSON

示例

Select A.[email]
      ,Email1 = JSON_VALUE(S,'$[0]')
      ,Email2 = JSON_VALUE(S,'$[1]')
      ,Email3 = JSON_VALUE(S,'$[2]')
 From YourTable  A
 Cross Apply ( values ( '["'+replace(replace(email,' ',''),';','","')+'"]' ) ) B(S)

结果

email               Email1      Email2      Email3
abc@y.aa; abc@z.bb  abc@y.aa    abc@z.bb    NULL
pqr@y.bb; pqr@x.cc  pqr@y.bb    pqr@x.cc    NULL
xyx@y.dd; xyx@z.pp  xyx@y.dd    xyx@z.pp    NULL

【讨论】:

  • 谢谢,但出现错误 - JSON 文本格式不正确。在位置 1 发现了意外的字符“”。
  • @cool_taps 不清楚您遇到的错误。看看dbfiddle.uk/…
  • @cool_taps,请不要错过我的 cmets 谈论最小可重现示例
【解决方案2】:

这里有两种方法:

    DECLARE @email TABLE (Email VARCHAR(1000));
    INSERT @email VALUES('abc@y.aa; abc@z.bb'),('pqr@y.bb; pqr@x.cc'),('xyx@y.dd; xyx@z.pp');
    
    --==== 1. Using APPLY
    SELECT 
      EmailGroup  = e.Email,
      Email       = email1.E1
    FROM   @email AS e
    CROSS APPLY (VALUES
        ( SUBSTRING(e.Email, 0, CHARINDEX(';', e.email)      ) ),
        ( SUBSTRING(e.Email, CHARINDEX(';', e.email) + 1, 8000) )
    ) AS email1(E1);
    
    --==== 2. Using STRING_SPLIT
    SELECT e.Email, split.[value]
    FROM   @email AS e
    CROSS APPLY STRING_SPLIT(e.Email,';') AS split;

两者都返回:

EmailGroup              Email
----------------------- -------------
abc@y.aa; abc@z.bb      abc@y.aa
abc@y.aa; abc@z.bb      abc@z.bb
pqr@y.bb; pqr@x.cc      pqr@x.cc
pqr@y.bb; pqr@x.cc      pqr@y.bb
xyx@y.dd; xyx@z.pp      xyx@y.dd
xyx@y.dd; xyx@z.pp      xyx@z.pp

对于同一行的两封电子邮件:

SELECT 
  EmailGroup = e.Email,
  Email1     = SUBSTRING(e.Email,0,CHARINDEX(';',e.email)),
  Email2     = SUBSTRING(e.Email,CHARINDEX(';',e.email)+1,8000)
FROM   @email AS e;

EmailGroup             Email1     Email2
---------------------- ---------- ---------------
abc@y.aa; abc@z.bb     abc@y.aa    abc@z.bb
pqr@y.bb; pqr@x.cc     pqr@y.bb    pqr@x.cc
xyx@y.dd; xyx@z.pp     xyx@y.dd    xyx@z.pp

【讨论】:

  • @Alan Burstein - 谢谢!第二个版本正在运行。我正确收到了 2 封电子邮件。在某些情况下,它有 3 封电子邮件,那么我应该进行哪些更改才能获得 Email3?
  • 谢谢@Charlieface 我会尽快更新第一个解决方案
【解决方案3】:

试试这个:

Declare @testTable Table (Email varchar(100));
 Insert Into @testTable (Email)
 Values ('abc@a.aa')
      , ('abc@y.aa; abc@z.bb')
      , ('pqr@y.bb; pqr@x.cc; pqr@z.dd')
      , ('xyx@y.dd; xyx@z.pp');

 Select tt.Email
      , email1 = ltrim(substring(v.email, 1, p01.pos - 2))
      , email2 = ltrim(substring(v.email, p01.pos, p02.pos - p01.pos - 1))
      , email3 = ltrim(substring(v.email, p02.pos, p03.pos - p02.pos - 1))
   From @testTable                                              As tt
  Cross Apply (Values (concat(tt.Email, replicate(';', 3))))    As v(email)
  Cross Apply (Values (charindex(';', v.email, 1) + 1))         As p01(pos)
  Cross Apply (Values (charindex(';', v.email, p01.pos) + 1))   As p02(pos)
  Cross Apply (Values (charindex(';', v.email, p02.pos) + 1))   As p03(pos)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多