如何分隔多个分隔数据并在一列中连接

时间:2017-05-14 04:26:55

标签: sql

我有这样的表数据:

Id  NAME

1   Cleo Bond;Smith Brian;James Jiff Bond;Alice; Gray Tin Ronald Downell

我想分隔分号分隔的字符串,删除所有空格,从每个名称中取出初始字符,然后将值与空格连接起来。 输出应该是:

Id  Name  

1   CB SM JJB A GTRD

我该怎么做?

2 个答案:

答案 0 :(得分:0)

你应该从不在一个单元格中存储多个值!

字符分隔列表是一个痛苦的问题......

更多:请不要在没有说明您的实际RDBMS(oracle,SQL Server,MySQL,其他)及其版本的情况下提出SQL相关问题!

此解决方案需要各种字符串操作。每个RDBMS的工作方式都不同,尽管有一些常识

以下是SQL-Server方法。你会得到方向......

我通过XML使用内联拆分器(有许多方法/功能/工具可供查找!)首先以分号分隔字符串,而不是空白处的部分。第一个字母重新连接。首先只是,在第二步中所有的一起都是空白:

DECLARE @mockup TABLE(Id INT,NAME VARCHAR(1000));
INSERT INTO @mockup VALUES
 (1,'Cleo Bond;Smith Brian;James Jiff Bond;Alice; Gray Tin Ronald Downell');

WITH Names AS
(
    SELECT m.Id
          ,m.NAME
          ,C_Key
          ,LEFT(UPPER(F.NamePart.value(N'text()[1]','nvarchar(max)')),1) AS Initial
    FROM @mockup AS m
    CROSS APPLY(SELECT m.NAME
                      ,CAST('<x>' + REPLACE((SELECT m.NAME AS [*] FOR XML PATH('')),';','</x><x>') + '</x>' AS XML)) AS A(A_Key,AllParts)
    CROSS APPLY A.AllParts.nodes(N'/x[text()]') AS B(Part)
    CROSS APPLY(SELECT B.Part.value(N'text()[1]',N'nvarchar(max)')
                      ,CAST('<y>' + REPLACE((SELECT B.Part.value(N'text()[1]',N'nvarchar(max)') AS [*] FOR XML PATH('')),' ','</y><y>') + '</y>' AS XML)) AS C(C_Key,PersParts)
    CROSS APPLY C.PersParts.nodes(N'/y[text()]') AS D(PersPart)
    CROSS APPLY(SELECT D.PersPart.value(N'text()[1]',N'nvarchar(max)')
                      ,CAST('<z>' + REPLACE((SELECT D.PersPart.value(N'text()[1]',N'nvarchar(max)') AS [*] FOR XML PATH('')),' ','</z><z>') + '</z>' AS XML)) AS E(E_Key,NameParts)
    CROSS APPLY E.NameParts.nodes('/z[text()]') AS F(NamePart)
)
,AllInitials AS
(
    SELECT outerN.Id
          ,outerN.NAME
          ,outerN.C_Key
          ,(SELECT innerN.Initial AS [*] FROM Names AS innerN WHERE innerN.C_Key=outerN.C_Key FOR XML PATH('')) AS Initials
    FROM Names AS outerN
    GROUP BY Id,NAME,C_Key
)
SELECT outerAI.Id
      ,outerAI.NAME
      ,STUFF((SELECT ' ' + innerAI.Initials AS [*] FROM AllInitials AS innerAI WHERE innerAI.Id=outerAI.Id FOR XML PATH('')),1,1,'') AS Initials
FROM AllInitials AS outerAI
GROUP BY outerAI.Id,outerAI.NAME;

我必须承认,我这样做只是为了好玩......这个解决方案是丑陋和错误的(两个不同的人,同名,非法字符,NULL)...我永远不会试图在现实生活采用这样的方法。尝试先更改原始数据!

答案 1 :(得分:0)

这是Postgres的解决方案:

SDL
-- prepare test data
create table data (id integer, name text);
insert into data (id, name)
values (1,'Cleo Bond;Smith Brian;James Jiff Bond;Alice; Gray Tin Ronald Downell');

在线示例:http://rextester.com/HFDBW27664

但这是一个可怕的数据模型,你应该真正规范化。