【问题标题】:String Split into column instead of rows字符串拆分为列而不是行
【发布时间】:2018-05-14 19:53:02
【问题描述】:

样本数据:

id  email_address                                   email_new
-------------------------------------------------------------------------------
1   a.b@wellsfargoadvisors.com                      a.b@wellsfargoadvisors.com
2   c.b@RaymondJames.com; abc@RaymondJames.com      c.b@RaymondJames.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
3   a.b@boa.com; bbc@boa.com; hh@bankofamerica.com  bbc@boa.com
3   a.b@boa.com; bbc@boa.com; hh@bankofamerica.com  hh@bankofamerica.com

我使用以下查询将“;”分隔的字符串拆分为行:

SELECT
    id, email_address, email_new
FROM 
    (SELECT 
         id, email_address, 
         Split.a.value('.', 'NVARCHAR(max)') AS email_new 
     FROM
         (SELECT 
              id, email_address, CAST ('<M>' + REPLACE(email_address, '; ', '</M><M>') + '</M>' AS XML) email_new
          FROM 
              table) AS A 
     CROSS APPLY 
         email_new.nodes ('/M') AS Split(a)) x
GROUP BY
    id, email_address, email_new

我的查询的问题是我不想为每个拆分的电子邮件地址创建一个新行 - 我想为其添加一个新列。理想情况下,类似于以下内容:

id  email_1                      email_2                email_3
------------------------------------------------------------------------------
1   a.b@wellsfargoadvisors.com   null                   null
2   c.b@RaymondJames.com         abc@RaymondJames.com   null
3   a.b@boa.com                  bbc@boa.com            h@bankofamerica.com

email_address 列中有多达 3 个单独的电子邮件地址。有什么建议么?如果它超过 3- 最好是 answer 可以占 n 列。

【问题讨论】:

  • 总是有分号吗?您可以只使用substring(),也可以使用 ID 将其拆分,然后您可以将其转回列中
  • 您可能会收到多少封电子邮件?
  • @Random_User 它们总是以相同的方式分隔:分号和空格'; '
  • @M.Ali email_address 中有多少单独的电子邮件?最多 3 个
  • 谢谢@JohnCappelletti - 在发布之前没有看到之前的帖子。

标签: sql sql-server


【解决方案1】:

测试数据

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'      , 'c.b@RaymondJames.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'               ),
(3   ,'a.b@boa.com; bbc@boa.com; hh@bankofamerica.com'  , 'bbc@boa.com'               ),
(3   ,'a.b@boa.com; bbc@boa.com; hh@bankofamerica.com'  , 'hh@bankofamerica.com'      );

查询

WITH Emails (ID , XmlEmail, email_new)
AS
(
    SELECT Id
          , CONVERT(XML,'<Emails><email>'  
                    + REPLACE(email_address,';', '</email><email>') 
                    + '</email></Emails>') AS XmlEmail
          , email_new
      FROM @t
)

 SELECT   ID
        , XmlEmail.value('/Emails[1]/email[1]','varchar(100)') AS Email1
        , XmlEmail.value('/Emails[1]/email[2]','varchar(100)') AS Email2
        , XmlEmail.value('/Emails[1]/email[3]','varchar(100)') AS Email3
        , XmlEmail.value('/Emails[1]/email[4]','varchar(100)') AS Email4
        , XmlEmail.value('/Emails[1]/email[5]','varchar(100)') AS Email5
        , email_new
FROM Emails

结果

╔════╦════════════════════════════╦═══════════════════════╦═══════════════════════╦═════════╦═════════╦════════════════════════════╗
║ ID ║           Email1           ║        Email2         ║        Email3         ║ Email4  ║ Email5  ║         email_new          ║
╠════╬════════════════════════════╬═══════════════════════╬═══════════════════════╬═════════╬═════════╬════════════════════════════╣
║  1 ║ a.b@wellsfargoadvisors.com ║ NULL                  ║ NULL                  ║ NULL    ║ NULL    ║ a.b@wellsfargoadvisors.com ║
║  2 ║ c.b@RaymondJames.com       ║  abc@RaymondJames.com ║ NULL                  ║ NULL    ║ NULL    ║ c.b@RaymondJames.com       ║
║  2 ║ c.b@RaymondJames.com       ║  abc@RaymondJames.com ║ NULL                  ║ NULL    ║ NULL    ║ abc@RaymondJames.com       ║
║  3 ║ a.b@boa.com                ║  bbc@boa.com          ║  hh@bankofamerica.com ║ NULL    ║ NULL    ║ a.b@boa.com                ║
║  3 ║ a.b@boa.com                ║  bbc@boa.com          ║  hh@bankofamerica.com ║ NULL    ║ NULL    ║ bbc@boa.com                ║
║  3 ║ a.b@boa.com                ║  bbc@boa.com          ║  hh@bankofamerica.com ║ NULL    ║ NULL    ║ hh@bankofamerica.com       ║
╚════╩════════════════════════════╩═══════════════════════╩═══════════════════════╩═════════╩═════════╩════════════════════════════╝

【讨论】:

  • 谢谢!我调整了';'到 '; '而且效果很好。我有任何机会不指定列数 - 因为它是基于 # of '; 创建的' 拆分条目?
  • @user8834780 为此,您需要查看 Dynamic Pivot。这本身就是一个完全不同的野兽。
  • 听起来很吓人,就像一个全新的问题。我就这样吧。谢谢!
猜你喜欢
  • 2011-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多