如何将多值,字符分隔的列拆分为多行?

时间:2017-11-30 15:59:00

标签: sql-server tsql sql-server-2012

长时间潜伏,第一次提问者......

虽然看起来很熟悉,但我还没有找到这个具体问题的答案。

我有一个包含以分号分隔的值列表的列的表。该表是应用程序列表以及与该应用程序关联的服务器。服务器列表以分号分隔,但分为serverId; serverName为x个服务器 - 有一些应用程序与数百个服务器相关联,一些与1相关联,一些与0相关联。我想分开此服务器列为每个唯一服务器的行,包括表中的Id以及serverId和serverName作为列。

数据目前看起来像这样

applicationId\Servers 1\serverId1;serverName1 2\serverId2;serverName2;serverId3;serverName3 3\serverId1;serverName1;serverId5;serverName5;serverId8;serverName8 4\serverId9;serverName9 5\

我想创建一个包含applicationId,serverId和serverName列的新表,如下所示:

applicationId\serverId\serverName 1\serverId1\serverName1 2\serverId2\serverName2 2\serverId3\serverName3 3\serverId1\serverName1 3\serverId5\serverName5 3\serverId8\serverName8 4\serverId9\serverName9 5\

或者,如果我可以将serverId放到带有applicationId的表中,那么它会很有用,因为我有一个带有serverId和serverName的表。

applicationId\serverId

我尝试将列拆分为';'但是产生的输出不是很有用,如下所示:

applicationId\serverColumn 1\serverId1 1\serverName1 2\serverId2 2\serverName2 2\serverId3 2\serverName3 ....

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:2)

至少可以说这只是一个糟糕的数据结构。但是有可能使用Jeff Moden的分离器。 http://www.sqlservercentral.com/articles/Tally+Table/72993/我知道你说你有一个分裂器但是如果它有一个循环或递归cte你需要把它扔掉像杰夫那样的基于它的集合。

这是一个功能齐全的例子,说明如何利用他的分离器来完成这项工作。

declare @Something table 
(
    ApplicationID int
    , ServerInfo varchar(100))
insert @Something 
(
    ApplicationID
    , ServerInfo
) values
(1, 'serverId1;serverName1')
, (2, 'serverId2;serverName2;serverId3;serverName3')
, (3, 'serverId1;serverName1;serverId5;serverName5;serverId8;serverName8')
, (4, 'serverId9;serverName9')
;

with ServerIDs as
(
    select s.ApplicationID
        , ServerID = case when x.ItemNumber % 2 = 1 then x.Item end
        , x.ItemNumber
    from @Something s
    cross apply dbo.DelimitedSplit8K(s.ServerInfo, ';') x
    where x.ItemNumber % 2 = 1
)
, ServerNames as
(
    select s.ApplicationID
        , ServerName = case when x.ItemNumber % 2 = 0 then x.Item end
        , x.ItemNumber
    from @Something s
    cross apply dbo.DelimitedSplit8K(s.ServerInfo, ';') x
    where x.ItemNumber % 2 = 0
)

select si.ApplicationID
    , si.ServerID
    , sn.ServerName
from ServerIDs si
join ServerNames sn on sn.ApplicationID = si.ApplicationID and si.ItemNumber + 1 = sn.ItemNumber

返回:

ApplicationID   ServerID    ServerName
1               serverId1   serverName1
2               serverId2   serverName2
2               serverId3   serverName3
3               serverId1   serverName1
3               serverId5   serverName5
3               serverId8   serverName8
4               serverId9   serverName9