字符串拆分为列而不是行

时间:2018-05-14 19:53:02

标签: sql sql-server

示例数据:

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,最好是答案可以占n列。

1 个答案:

答案 0 :(得分:2)

测试数据

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       ║
╚════╩════════════════════════════╩═══════════════════════╩═══════════════════════╩═════════╩═════════╩════════════════════════════╝