Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在SQLServer数据库中使用函数/存储过程实现以下功能_Sql_Sql Server_Sql Function - Fatal编程技术网

如何在SQLServer数据库中使用函数/存储过程实现以下功能

如何在SQLServer数据库中使用函数/存储过程实现以下功能,sql,sql-server,sql-function,Sql,Sql Server,Sql Function,我有下表,其中包含以下数据: Tab1 FutureMISBoundaryVersion CurrentMISBoundaryVersion FutureHAMBoundaryVersion CurrentHAMBoundaryVersion 2:21,5:50,4:55,7:80,9:33 2:12,5:40,4:35,7:60,9:87 2:52,5:90,4:75,7:30,9:57 2

我有下表,其中包含以下数据:

                                            Tab1
FutureMISBoundaryVersion  CurrentMISBoundaryVersion  FutureHAMBoundaryVersion  CurrentHAMBoundaryVersion 
2:21,5:50,4:55,7:80,9:33  2:12,5:40,4:35,7:60,9:87   2:52,5:90,4:75,7:30,9:57  2:42,5:60,4:95,7:70,9:37   
必须将该键值对拆分为多个键,并且必须以以下方式将每个键的值插入到另一个表中

FutureMIS-OAKVersion |FutureMIS-HAMVersion |FutureMIS-DURVersion | FutureMIS-BURVersion| FutureMIS-YRTVersion |DeviceMIS-OAKVersion|DeviceMIS-HAMVersion |DeviceMIS-DURVersion| DeviceMIS-BURVersion| DeviceMIS-YRTVersion
              33     |              80     |            21       |            55       |  50                  | 87                 |  60                 |12                  |35                   | 40
i、 e:当它在tab1中找到“FutureMISBoundaryVersion”列时,它的值 “2:21,5:50,4:55,7:80,9:33”将被拆分,其值的插入方式应确保键2 i,e:21的相应值将插入FutureMIS DURVersion列

类似地,键5的值50将插入FutureMIS BURVersion列,以此类推,用于其他键

当它找到列“CurrentMISBoundaryVersion”时,则
“2:12,5:40,4:35,7:60,9:87”将被拆分,其值的插入方式是,键2 i,e:12的相应值将插入到CurrentMIS Durvision列中,类似地,键5的40值将插入到DeviceMIS YRTVersion列中,以此类推,用于源表的其他列


表结构可能会扩展,因为我只显示了4个源表列,但所有列的逻辑保持不变

以下查询将把逗号分隔的字符串
2:21,5:50,4:55,7:80,9:33
解析为单个组件
2:21
5:30
等。从那里,您可以使用类似的方法从
aa:bb
提取
bb

由于键值对的格式为
aa:bb
,因此可以使用
datepart(hour,'aa:bb')
datepart(minute,'aa:bb')
提取
aa
bb

; with 
Tab1 as
(
    select  val  = '2:21,5:50,4:55,7:80,9:33'
)
select  t.*, k1.k, k2.k, k3.k, k4.k, k5.k
from    Tab1 t
    cross apply
    (
        select  i = charindex(',', t.val),
            k = substring(t.val, 1, charindex(',', t.val + ',', 1) - 1)
    ) k1
    cross apply
    (
        select  i = charindex(',', t.val, k1.i + 1),
            k = substring(t.val, k1.i + 1, charindex(',', t.val + ',', k1.i + 1) - k1.i - 1)
    ) k2
    cross apply
    (
        select  i = charindex(',', t.val, k2.i + 1),
            k = substring(t.val, k2.i + 1, charindex(',', t.val + ',', k2.i + 1) - k2.i - 1)
    ) k3
    cross apply
    (
        select  i = charindex(',', t.val, k3.i + 1),
            k = substring(t.val, k3.i + 1, charindex(',', t.val + ',', k3.i + 1) - k3.i - 1)
    ) k4
    cross apply
    (
        select  i = charindex(',', t.val, k4.i + 1),
            k = substring(t.val, k4.i + 1, charindex(',', t.val + ',', k4.i + 1) - k4.i - 1)
    ) k5

下面的查询将把逗号分隔的字符串
2:21,5:50,4:55,7:80,9:33
解析为单个组件
2:21
5:30
等。从那里,您可以使用类似的方法从
aa:bb
中提取
bb

由于键值对的格式为
aa:bb
,因此可以使用
datepart(hour,'aa:bb')
datepart(minute,'aa:bb')
提取
aa
bb

; with 
Tab1 as
(
    select  val  = '2:21,5:50,4:55,7:80,9:33'
)
select  t.*, k1.k, k2.k, k3.k, k4.k, k5.k
from    Tab1 t
    cross apply
    (
        select  i = charindex(',', t.val),
            k = substring(t.val, 1, charindex(',', t.val + ',', 1) - 1)
    ) k1
    cross apply
    (
        select  i = charindex(',', t.val, k1.i + 1),
            k = substring(t.val, k1.i + 1, charindex(',', t.val + ',', k1.i + 1) - k1.i - 1)
    ) k2
    cross apply
    (
        select  i = charindex(',', t.val, k2.i + 1),
            k = substring(t.val, k2.i + 1, charindex(',', t.val + ',', k2.i + 1) - k2.i - 1)
    ) k3
    cross apply
    (
        select  i = charindex(',', t.val, k3.i + 1),
            k = substring(t.val, k3.i + 1, charindex(',', t.val + ',', k3.i + 1) - k3.i - 1)
    ) k4
    cross apply
    (
        select  i = charindex(',', t.val, k4.i + 1),
            k = substring(t.val, k4.i + 1, charindex(',', t.val + ',', k4.i + 1) - k4.i - 1)
    ) k5

老实说,这是非常时髦的要求。 请注意,以下解决方案仅在SQL Server 2016+中有效,因为我使用JSON解析数据。然而,您可以编写自己的解析器,在这种情况下,代码将在几乎所有版本的SQL Server中工作

解析函数:

CREATE FUNCTION dbo.ParseIt(@Type NVARCHAR(255),@Value NVARCHAR(MAX))
RETURNS @Parsed TABLE (Code NVARCHAR(255),Value NVARCHAR(255))
AS
BEGIN
    INSERT INTO @Parsed(Code,Value)
    SELECT @Type + '-' + m.Code + 'Version' AS [Code],p.[1] AS [Value]
    FROM (
        SELECT j.[key] AS [ID],i.[key],i.value
        FROM OPENJSON('["' + REPLACE(@Value,',','","') + '"]') j
        CROSS APPLY OPENJSON('[' + REPLACE(j.[value],':',',') + ']') i
    ) a
    PIVOT(MAX(a.value) FOR a.[key] IN ([0],[1])) p
    INNER JOIN ( VALUES
        (2,'DUR')
        ,(4,'BUR')
        ,(5,'YRT')
        ,(7,'HAM')
        ,(9,'OAK')
    ) m(ID, Code) ON m.ID = p.[0]
    ;
    RETURN;
END
DECLARE @Table TABLE (FutureMISBoundaryVersion NVARCHAR(MAX), CurrentMISBoundaryVersion NVARCHAR(MAX),FutureHAMBoundaryVersion NVARCHAR(MAX),CurrentHAMBoundaryVersion NVARCHAR(MAX));
INSERT INTO @Table(FutureMISBoundaryVersion,CurrentMISBoundaryVersion,FutureHAMBoundaryVersion,CurrentHAMBoundaryVersion)VALUES
    ('2:21,5:50,4:55,7:80,9:33','2:12,5:40,4:35,7:60,9:87','2:52,5:90,4:75,7:30,9:57','2:42,5:60,4:95,7:70,9:37')
;
SELECT COALESCE(p.[FutureMIS-OAKVersion],'') AS [FutureMIS-OAKVersion]
    ,COALESCE(p.[FutureMIS-HAMVersion],'') AS [FutureMIS-HAMVersion]
    ,COALESCE(p.[FutureMIS-DURVersion],'') AS [FutureMIS-DURVersion]
    ,COALESCE(p.[FutureMIS-BURVersion],'') AS [FutureMIS-BURVersion]
    ,COALESCE(p.[FutureMIS-YRTVersion],'') AS [FutureMIS-YRTVersion]
    ,COALESCE(p.[DeviceMIS-OAKVersion],'') AS [DeviceMIS-OAKVersion]
    ,COALESCE(p.[DeviceMIS-HAMVersion],'') AS [DeviceMIS-HAMVersion]
    ,COALESCE(p.[DeviceMIS-DURVersion],'') AS [DeviceMIS-DURVersion]
    ,COALESCE(p.[DeviceMIS-BURVersion],'') AS [DeviceMIS-BURVersion]
    ,COALESCE(p.[DeviceMIS-YRTVersion],'') AS [DeviceMIS-YRTVersion]
FROM (
    SELECT f.Code,f.Value FROM @Table t CROSS APPLY dbo.ParseIt('FutureMIS',t.FutureMISBoundaryVersion) f
    UNION ALL 
    SELECT f.Code,f.Value FROM @Table t CROSS APPLY dbo.ParseIt('DeviceMIS',t.CurrentMISBoundaryVersion) f
) a
PIVOT(MAX(a.Value) FOR a.Code IN ([DeviceMIS-BURVersion],[DeviceMIS-DURVersion],[DeviceMIS-HAMVersion],[DeviceMIS-OAKVersion]
    ,[DeviceMIS-YRTVersion],[FutureMIS-BURVersion],[FutureMIS-DURVersion],[FutureMIS-HAMVersion],[FutureMIS-OAKVersion]
    ,[FutureMIS-YRTVersion])) p
;
初始数据:

CREATE FUNCTION dbo.ParseIt(@Type NVARCHAR(255),@Value NVARCHAR(MAX))
RETURNS @Parsed TABLE (Code NVARCHAR(255),Value NVARCHAR(255))
AS
BEGIN
    INSERT INTO @Parsed(Code,Value)
    SELECT @Type + '-' + m.Code + 'Version' AS [Code],p.[1] AS [Value]
    FROM (
        SELECT j.[key] AS [ID],i.[key],i.value
        FROM OPENJSON('["' + REPLACE(@Value,',','","') + '"]') j
        CROSS APPLY OPENJSON('[' + REPLACE(j.[value],':',',') + ']') i
    ) a
    PIVOT(MAX(a.value) FOR a.[key] IN ([0],[1])) p
    INNER JOIN ( VALUES
        (2,'DUR')
        ,(4,'BUR')
        ,(5,'YRT')
        ,(7,'HAM')
        ,(9,'OAK')
    ) m(ID, Code) ON m.ID = p.[0]
    ;
    RETURN;
END
DECLARE @Table TABLE (FutureMISBoundaryVersion NVARCHAR(MAX), CurrentMISBoundaryVersion NVARCHAR(MAX),FutureHAMBoundaryVersion NVARCHAR(MAX),CurrentHAMBoundaryVersion NVARCHAR(MAX));
INSERT INTO @Table(FutureMISBoundaryVersion,CurrentMISBoundaryVersion,FutureHAMBoundaryVersion,CurrentHAMBoundaryVersion)VALUES
    ('2:21,5:50,4:55,7:80,9:33','2:12,5:40,4:35,7:60,9:87','2:52,5:90,4:75,7:30,9:57','2:42,5:60,4:95,7:70,9:37')
;
SELECT COALESCE(p.[FutureMIS-OAKVersion],'') AS [FutureMIS-OAKVersion]
    ,COALESCE(p.[FutureMIS-HAMVersion],'') AS [FutureMIS-HAMVersion]
    ,COALESCE(p.[FutureMIS-DURVersion],'') AS [FutureMIS-DURVersion]
    ,COALESCE(p.[FutureMIS-BURVersion],'') AS [FutureMIS-BURVersion]
    ,COALESCE(p.[FutureMIS-YRTVersion],'') AS [FutureMIS-YRTVersion]
    ,COALESCE(p.[DeviceMIS-OAKVersion],'') AS [DeviceMIS-OAKVersion]
    ,COALESCE(p.[DeviceMIS-HAMVersion],'') AS [DeviceMIS-HAMVersion]
    ,COALESCE(p.[DeviceMIS-DURVersion],'') AS [DeviceMIS-DURVersion]
    ,COALESCE(p.[DeviceMIS-BURVersion],'') AS [DeviceMIS-BURVersion]
    ,COALESCE(p.[DeviceMIS-YRTVersion],'') AS [DeviceMIS-YRTVersion]
FROM (
    SELECT f.Code,f.Value FROM @Table t CROSS APPLY dbo.ParseIt('FutureMIS',t.FutureMISBoundaryVersion) f
    UNION ALL 
    SELECT f.Code,f.Value FROM @Table t CROSS APPLY dbo.ParseIt('DeviceMIS',t.CurrentMISBoundaryVersion) f
) a
PIVOT(MAX(a.Value) FOR a.Code IN ([DeviceMIS-BURVersion],[DeviceMIS-DURVersion],[DeviceMIS-HAMVersion],[DeviceMIS-OAKVersion]
    ,[DeviceMIS-YRTVersion],[FutureMIS-BURVersion],[FutureMIS-DURVersion],[FutureMIS-HAMVersion],[FutureMIS-OAKVersion]
    ,[FutureMIS-YRTVersion])) p
;
代码:

CREATE FUNCTION dbo.ParseIt(@Type NVARCHAR(255),@Value NVARCHAR(MAX))
RETURNS @Parsed TABLE (Code NVARCHAR(255),Value NVARCHAR(255))
AS
BEGIN
    INSERT INTO @Parsed(Code,Value)
    SELECT @Type + '-' + m.Code + 'Version' AS [Code],p.[1] AS [Value]
    FROM (
        SELECT j.[key] AS [ID],i.[key],i.value
        FROM OPENJSON('["' + REPLACE(@Value,',','","') + '"]') j
        CROSS APPLY OPENJSON('[' + REPLACE(j.[value],':',',') + ']') i
    ) a
    PIVOT(MAX(a.value) FOR a.[key] IN ([0],[1])) p
    INNER JOIN ( VALUES
        (2,'DUR')
        ,(4,'BUR')
        ,(5,'YRT')
        ,(7,'HAM')
        ,(9,'OAK')
    ) m(ID, Code) ON m.ID = p.[0]
    ;
    RETURN;
END
DECLARE @Table TABLE (FutureMISBoundaryVersion NVARCHAR(MAX), CurrentMISBoundaryVersion NVARCHAR(MAX),FutureHAMBoundaryVersion NVARCHAR(MAX),CurrentHAMBoundaryVersion NVARCHAR(MAX));
INSERT INTO @Table(FutureMISBoundaryVersion,CurrentMISBoundaryVersion,FutureHAMBoundaryVersion,CurrentHAMBoundaryVersion)VALUES
    ('2:21,5:50,4:55,7:80,9:33','2:12,5:40,4:35,7:60,9:87','2:52,5:90,4:75,7:30,9:57','2:42,5:60,4:95,7:70,9:37')
;
SELECT COALESCE(p.[FutureMIS-OAKVersion],'') AS [FutureMIS-OAKVersion]
    ,COALESCE(p.[FutureMIS-HAMVersion],'') AS [FutureMIS-HAMVersion]
    ,COALESCE(p.[FutureMIS-DURVersion],'') AS [FutureMIS-DURVersion]
    ,COALESCE(p.[FutureMIS-BURVersion],'') AS [FutureMIS-BURVersion]
    ,COALESCE(p.[FutureMIS-YRTVersion],'') AS [FutureMIS-YRTVersion]
    ,COALESCE(p.[DeviceMIS-OAKVersion],'') AS [DeviceMIS-OAKVersion]
    ,COALESCE(p.[DeviceMIS-HAMVersion],'') AS [DeviceMIS-HAMVersion]
    ,COALESCE(p.[DeviceMIS-DURVersion],'') AS [DeviceMIS-DURVersion]
    ,COALESCE(p.[DeviceMIS-BURVersion],'') AS [DeviceMIS-BURVersion]
    ,COALESCE(p.[DeviceMIS-YRTVersion],'') AS [DeviceMIS-YRTVersion]
FROM (
    SELECT f.Code,f.Value FROM @Table t CROSS APPLY dbo.ParseIt('FutureMIS',t.FutureMISBoundaryVersion) f
    UNION ALL 
    SELECT f.Code,f.Value FROM @Table t CROSS APPLY dbo.ParseIt('DeviceMIS',t.CurrentMISBoundaryVersion) f
) a
PIVOT(MAX(a.Value) FOR a.Code IN ([DeviceMIS-BURVersion],[DeviceMIS-DURVersion],[DeviceMIS-HAMVersion],[DeviceMIS-OAKVersion]
    ,[DeviceMIS-YRTVersion],[FutureMIS-BURVersion],[FutureMIS-DURVersion],[FutureMIS-HAMVersion],[FutureMIS-OAKVersion]
    ,[FutureMIS-YRTVersion])) p
;

老实说,这是非常时髦的要求。 请注意,以下解决方案仅在SQL Server 2016+中有效,因为我使用JSON解析数据。然而,您可以编写自己的解析器,在这种情况下,代码将在几乎所有版本的SQL Server中工作

解析函数:

CREATE FUNCTION dbo.ParseIt(@Type NVARCHAR(255),@Value NVARCHAR(MAX))
RETURNS @Parsed TABLE (Code NVARCHAR(255),Value NVARCHAR(255))
AS
BEGIN
    INSERT INTO @Parsed(Code,Value)
    SELECT @Type + '-' + m.Code + 'Version' AS [Code],p.[1] AS [Value]
    FROM (
        SELECT j.[key] AS [ID],i.[key],i.value
        FROM OPENJSON('["' + REPLACE(@Value,',','","') + '"]') j
        CROSS APPLY OPENJSON('[' + REPLACE(j.[value],':',',') + ']') i
    ) a
    PIVOT(MAX(a.value) FOR a.[key] IN ([0],[1])) p
    INNER JOIN ( VALUES
        (2,'DUR')
        ,(4,'BUR')
        ,(5,'YRT')
        ,(7,'HAM')
        ,(9,'OAK')
    ) m(ID, Code) ON m.ID = p.[0]
    ;
    RETURN;
END
DECLARE @Table TABLE (FutureMISBoundaryVersion NVARCHAR(MAX), CurrentMISBoundaryVersion NVARCHAR(MAX),FutureHAMBoundaryVersion NVARCHAR(MAX),CurrentHAMBoundaryVersion NVARCHAR(MAX));
INSERT INTO @Table(FutureMISBoundaryVersion,CurrentMISBoundaryVersion,FutureHAMBoundaryVersion,CurrentHAMBoundaryVersion)VALUES
    ('2:21,5:50,4:55,7:80,9:33','2:12,5:40,4:35,7:60,9:87','2:52,5:90,4:75,7:30,9:57','2:42,5:60,4:95,7:70,9:37')
;
SELECT COALESCE(p.[FutureMIS-OAKVersion],'') AS [FutureMIS-OAKVersion]
    ,COALESCE(p.[FutureMIS-HAMVersion],'') AS [FutureMIS-HAMVersion]
    ,COALESCE(p.[FutureMIS-DURVersion],'') AS [FutureMIS-DURVersion]
    ,COALESCE(p.[FutureMIS-BURVersion],'') AS [FutureMIS-BURVersion]
    ,COALESCE(p.[FutureMIS-YRTVersion],'') AS [FutureMIS-YRTVersion]
    ,COALESCE(p.[DeviceMIS-OAKVersion],'') AS [DeviceMIS-OAKVersion]
    ,COALESCE(p.[DeviceMIS-HAMVersion],'') AS [DeviceMIS-HAMVersion]
    ,COALESCE(p.[DeviceMIS-DURVersion],'') AS [DeviceMIS-DURVersion]
    ,COALESCE(p.[DeviceMIS-BURVersion],'') AS [DeviceMIS-BURVersion]
    ,COALESCE(p.[DeviceMIS-YRTVersion],'') AS [DeviceMIS-YRTVersion]
FROM (
    SELECT f.Code,f.Value FROM @Table t CROSS APPLY dbo.ParseIt('FutureMIS',t.FutureMISBoundaryVersion) f
    UNION ALL 
    SELECT f.Code,f.Value FROM @Table t CROSS APPLY dbo.ParseIt('DeviceMIS',t.CurrentMISBoundaryVersion) f
) a
PIVOT(MAX(a.Value) FOR a.Code IN ([DeviceMIS-BURVersion],[DeviceMIS-DURVersion],[DeviceMIS-HAMVersion],[DeviceMIS-OAKVersion]
    ,[DeviceMIS-YRTVersion],[FutureMIS-BURVersion],[FutureMIS-DURVersion],[FutureMIS-HAMVersion],[FutureMIS-OAKVersion]
    ,[FutureMIS-YRTVersion])) p
;
初始数据:

CREATE FUNCTION dbo.ParseIt(@Type NVARCHAR(255),@Value NVARCHAR(MAX))
RETURNS @Parsed TABLE (Code NVARCHAR(255),Value NVARCHAR(255))
AS
BEGIN
    INSERT INTO @Parsed(Code,Value)
    SELECT @Type + '-' + m.Code + 'Version' AS [Code],p.[1] AS [Value]
    FROM (
        SELECT j.[key] AS [ID],i.[key],i.value
        FROM OPENJSON('["' + REPLACE(@Value,',','","') + '"]') j
        CROSS APPLY OPENJSON('[' + REPLACE(j.[value],':',',') + ']') i
    ) a
    PIVOT(MAX(a.value) FOR a.[key] IN ([0],[1])) p
    INNER JOIN ( VALUES
        (2,'DUR')
        ,(4,'BUR')
        ,(5,'YRT')
        ,(7,'HAM')
        ,(9,'OAK')
    ) m(ID, Code) ON m.ID = p.[0]
    ;
    RETURN;
END
DECLARE @Table TABLE (FutureMISBoundaryVersion NVARCHAR(MAX), CurrentMISBoundaryVersion NVARCHAR(MAX),FutureHAMBoundaryVersion NVARCHAR(MAX),CurrentHAMBoundaryVersion NVARCHAR(MAX));
INSERT INTO @Table(FutureMISBoundaryVersion,CurrentMISBoundaryVersion,FutureHAMBoundaryVersion,CurrentHAMBoundaryVersion)VALUES
    ('2:21,5:50,4:55,7:80,9:33','2:12,5:40,4:35,7:60,9:87','2:52,5:90,4:75,7:30,9:57','2:42,5:60,4:95,7:70,9:37')
;
SELECT COALESCE(p.[FutureMIS-OAKVersion],'') AS [FutureMIS-OAKVersion]
    ,COALESCE(p.[FutureMIS-HAMVersion],'') AS [FutureMIS-HAMVersion]
    ,COALESCE(p.[FutureMIS-DURVersion],'') AS [FutureMIS-DURVersion]
    ,COALESCE(p.[FutureMIS-BURVersion],'') AS [FutureMIS-BURVersion]
    ,COALESCE(p.[FutureMIS-YRTVersion],'') AS [FutureMIS-YRTVersion]
    ,COALESCE(p.[DeviceMIS-OAKVersion],'') AS [DeviceMIS-OAKVersion]
    ,COALESCE(p.[DeviceMIS-HAMVersion],'') AS [DeviceMIS-HAMVersion]
    ,COALESCE(p.[DeviceMIS-DURVersion],'') AS [DeviceMIS-DURVersion]
    ,COALESCE(p.[DeviceMIS-BURVersion],'') AS [DeviceMIS-BURVersion]
    ,COALESCE(p.[DeviceMIS-YRTVersion],'') AS [DeviceMIS-YRTVersion]
FROM (
    SELECT f.Code,f.Value FROM @Table t CROSS APPLY dbo.ParseIt('FutureMIS',t.FutureMISBoundaryVersion) f
    UNION ALL 
    SELECT f.Code,f.Value FROM @Table t CROSS APPLY dbo.ParseIt('DeviceMIS',t.CurrentMISBoundaryVersion) f
) a
PIVOT(MAX(a.Value) FOR a.Code IN ([DeviceMIS-BURVersion],[DeviceMIS-DURVersion],[DeviceMIS-HAMVersion],[DeviceMIS-OAKVersion]
    ,[DeviceMIS-YRTVersion],[FutureMIS-BURVersion],[FutureMIS-DURVersion],[FutureMIS-HAMVersion],[FutureMIS-OAKVersion]
    ,[FutureMIS-YRTVersion])) p
;
代码:

CREATE FUNCTION dbo.ParseIt(@Type NVARCHAR(255),@Value NVARCHAR(MAX))
RETURNS @Parsed TABLE (Code NVARCHAR(255),Value NVARCHAR(255))
AS
BEGIN
    INSERT INTO @Parsed(Code,Value)
    SELECT @Type + '-' + m.Code + 'Version' AS [Code],p.[1] AS [Value]
    FROM (
        SELECT j.[key] AS [ID],i.[key],i.value
        FROM OPENJSON('["' + REPLACE(@Value,',','","') + '"]') j
        CROSS APPLY OPENJSON('[' + REPLACE(j.[value],':',',') + ']') i
    ) a
    PIVOT(MAX(a.value) FOR a.[key] IN ([0],[1])) p
    INNER JOIN ( VALUES
        (2,'DUR')
        ,(4,'BUR')
        ,(5,'YRT')
        ,(7,'HAM')
        ,(9,'OAK')
    ) m(ID, Code) ON m.ID = p.[0]
    ;
    RETURN;
END
DECLARE @Table TABLE (FutureMISBoundaryVersion NVARCHAR(MAX), CurrentMISBoundaryVersion NVARCHAR(MAX),FutureHAMBoundaryVersion NVARCHAR(MAX),CurrentHAMBoundaryVersion NVARCHAR(MAX));
INSERT INTO @Table(FutureMISBoundaryVersion,CurrentMISBoundaryVersion,FutureHAMBoundaryVersion,CurrentHAMBoundaryVersion)VALUES
    ('2:21,5:50,4:55,7:80,9:33','2:12,5:40,4:35,7:60,9:87','2:52,5:90,4:75,7:30,9:57','2:42,5:60,4:95,7:70,9:37')
;
SELECT COALESCE(p.[FutureMIS-OAKVersion],'') AS [FutureMIS-OAKVersion]
    ,COALESCE(p.[FutureMIS-HAMVersion],'') AS [FutureMIS-HAMVersion]
    ,COALESCE(p.[FutureMIS-DURVersion],'') AS [FutureMIS-DURVersion]
    ,COALESCE(p.[FutureMIS-BURVersion],'') AS [FutureMIS-BURVersion]
    ,COALESCE(p.[FutureMIS-YRTVersion],'') AS [FutureMIS-YRTVersion]
    ,COALESCE(p.[DeviceMIS-OAKVersion],'') AS [DeviceMIS-OAKVersion]
    ,COALESCE(p.[DeviceMIS-HAMVersion],'') AS [DeviceMIS-HAMVersion]
    ,COALESCE(p.[DeviceMIS-DURVersion],'') AS [DeviceMIS-DURVersion]
    ,COALESCE(p.[DeviceMIS-BURVersion],'') AS [DeviceMIS-BURVersion]
    ,COALESCE(p.[DeviceMIS-YRTVersion],'') AS [DeviceMIS-YRTVersion]
FROM (
    SELECT f.Code,f.Value FROM @Table t CROSS APPLY dbo.ParseIt('FutureMIS',t.FutureMISBoundaryVersion) f
    UNION ALL 
    SELECT f.Code,f.Value FROM @Table t CROSS APPLY dbo.ParseIt('DeviceMIS',t.CurrentMISBoundaryVersion) f
) a
PIVOT(MAX(a.Value) FOR a.Code IN ([DeviceMIS-BURVersion],[DeviceMIS-DURVersion],[DeviceMIS-HAMVersion],[DeviceMIS-OAKVersion]
    ,[DeviceMIS-YRTVersion],[FutureMIS-BURVersion],[FutureMIS-DURVersion],[FutureMIS-HAMVersion],[FutureMIS-OAKVersion]
    ,[FutureMIS-YRTVersion])) p
;

这是SQL Server中的一个难题。可以使用递归CTE执行此操作:

 with cte as (
      select convert(varchar(max), left(FutureMISBoundaryVersion, charindex(',', FutureMISBoundaryVersion) - 1)) as FutureMISBoundaryVersion,
             convert(varchar(max), left(CurrentMISBoundaryVersion, charindex(',', CurrentMISBoundaryVersion) - 1)) as CurrentMISBoundaryVersion,
             convert(varchar(max), left(FutureHAMBoundaryVersion, charindex(',', FutureHAMBoundaryVersion) - 1)) as FutureHAMBoundaryVersion,
             convert(varchar(max), left(CurrentHAMBoundaryVersion, charindex(',', FutureMISBoundaryVersion) - 1)) as CurrentHAMBoundaryVersion,
             stuff(FutureMISBoundaryVersion, 1, charindex(',', FutureMISBoundaryVersion), '') + ',' as FutureMISBoundaryVersion_rest,
             stuff(CurrentMISBoundaryVersion, 1, charindex(',', CurrentMISBoundaryVersion), '') + ',' as CurrentMISBoundaryVersion_rest,
             stuff(FutureHAMBoundaryVersion, 1, charindex(',', FutureHAMBoundaryVersion), '') + ',' as FutureHAMBoundaryVersion_rest,
             stuff(CurrentHAMBoundaryVersion, 1, charindex(',', CurrentHAMBoundaryVersion), '') + ',' as CurrentHAMBoundaryVersion_rest,
             1 as lev
      from t
      union all
      select convert(varchar(max), left(FutureMISBoundaryVersion_rest, charindex(',', FutureMISBoundaryVersion_rest) - 1)) as FutureMISBoundaryVersion,
             convert(varchar(max), left(CurrentMISBoundaryVersion_rest, charindex(',', CurrentMISBoundaryVersion_rest) - 1)) as CurrentMISBoundaryVersion,
             convert(varchar(max), left(FutureHAMBoundaryVersion_rest, charindex(',', FutureHAMBoundaryVersion_rest) - 1)) as FutureHAMBoundaryVersion,
             convert(varchar(max), left(CurrentHAMBoundaryVersion_rest, charindex(',', CurrentHAMBoundaryVersion_rest) - 1)) as CurrentHAMBoundaryVersion,
             stuff(FutureMISBoundaryVersion_rest, 1, charindex(',', FutureMISBoundaryVersion_rest), '') as FutureMISBoundaryVersion_rest,
             stuff(CurrentMISBoundaryVersion_rest, 1, charindex(',', CurrentMISBoundaryVersion_rest), '') as CurrentMISBoundaryVersion_rest,
             stuff(FutureHAMBoundaryVersion_rest, 1, charindex(',', FutureHAMBoundaryVersion_rest), '') as FutureHAMBoundaryVersion_rest,
             stuff(CurrentHAMBoundaryVersion_rest, 1, charindex(',', CurrentHAMBoundaryVersion_rest), '') as CurrentHAMBoundaryVersion_rest,
             lev + 1
      from cte
      where FutureMISBoundaryVersion_rest like '%,%'
     )
select FutureMISBoundaryVersion, CurrentMISBoundaryVersion, FutureHAMBoundaryVersion, CurrentHAMBoundaryVersion, lev
from cte;

这是SQL Server中的一个难题。可以使用递归CTE执行此操作:

 with cte as (
      select convert(varchar(max), left(FutureMISBoundaryVersion, charindex(',', FutureMISBoundaryVersion) - 1)) as FutureMISBoundaryVersion,
             convert(varchar(max), left(CurrentMISBoundaryVersion, charindex(',', CurrentMISBoundaryVersion) - 1)) as CurrentMISBoundaryVersion,
             convert(varchar(max), left(FutureHAMBoundaryVersion, charindex(',', FutureHAMBoundaryVersion) - 1)) as FutureHAMBoundaryVersion,
             convert(varchar(max), left(CurrentHAMBoundaryVersion, charindex(',', FutureMISBoundaryVersion) - 1)) as CurrentHAMBoundaryVersion,
             stuff(FutureMISBoundaryVersion, 1, charindex(',', FutureMISBoundaryVersion), '') + ',' as FutureMISBoundaryVersion_rest,
             stuff(CurrentMISBoundaryVersion, 1, charindex(',', CurrentMISBoundaryVersion), '') + ',' as CurrentMISBoundaryVersion_rest,
             stuff(FutureHAMBoundaryVersion, 1, charindex(',', FutureHAMBoundaryVersion), '') + ',' as FutureHAMBoundaryVersion_rest,
             stuff(CurrentHAMBoundaryVersion, 1, charindex(',', CurrentHAMBoundaryVersion), '') + ',' as CurrentHAMBoundaryVersion_rest,
             1 as lev
      from t
      union all
      select convert(varchar(max), left(FutureMISBoundaryVersion_rest, charindex(',', FutureMISBoundaryVersion_rest) - 1)) as FutureMISBoundaryVersion,
             convert(varchar(max), left(CurrentMISBoundaryVersion_rest, charindex(',', CurrentMISBoundaryVersion_rest) - 1)) as CurrentMISBoundaryVersion,
             convert(varchar(max), left(FutureHAMBoundaryVersion_rest, charindex(',', FutureHAMBoundaryVersion_rest) - 1)) as FutureHAMBoundaryVersion,
             convert(varchar(max), left(CurrentHAMBoundaryVersion_rest, charindex(',', CurrentHAMBoundaryVersion_rest) - 1)) as CurrentHAMBoundaryVersion,
             stuff(FutureMISBoundaryVersion_rest, 1, charindex(',', FutureMISBoundaryVersion_rest), '') as FutureMISBoundaryVersion_rest,
             stuff(CurrentMISBoundaryVersion_rest, 1, charindex(',', CurrentMISBoundaryVersion_rest), '') as CurrentMISBoundaryVersion_rest,
             stuff(FutureHAMBoundaryVersion_rest, 1, charindex(',', FutureHAMBoundaryVersion_rest), '') as FutureHAMBoundaryVersion_rest,
             stuff(CurrentHAMBoundaryVersion_rest, 1, charindex(',', CurrentHAMBoundaryVersion_rest), '') as CurrentHAMBoundaryVersion_rest,
             lev + 1
      from cte
      where FutureMISBoundaryVersion_rest like '%,%'
     )
select FutureMISBoundaryVersion, CurrentMISBoundaryVersion, FutureHAMBoundaryVersion, CurrentHAMBoundaryVersion, lev
from cte;


Squirrel:如果在键值对中找不到任何键,则会根据您的逻辑给出意外的o/p,即:不是这个'2:21,5:50,4:55,7:80,9:33',假设我们有这样的'5:50,4:55,7:80,9:33',那么整个解析过程都会出错。您是说第一个键总是
2
,第二个总是
5
?它不一定是!!顺序也可以改变,也就是说:它可以最大化包含它“2:21,5:50,4:55,7:80,9:33”中存在的所有键2,5,4,7,9,或者它可以“2:21,5:50,4:55”,但键将来自(2,5,4,7,9)的子集。如果未找到任何键,则相应列应为空字符串无论如何,您可以使用类似的方法,如
charindex()
substring()
,来提取@Squirrel所需的键和值:如果在键-值对中未找到任何键,则会从逻辑i中产生意外的o/p,e:与其说是“2:21,5:50,4:55,7:80,9:33”,不如说假设我们有这样的“5:50,4:55,7:80,9:33”,然后整个解析都搞砸了,你怎么知道缺了哪个键?你是说第一个键总是
2
,第二个键总是
5
?不必是!!顺序也可以改变,也就是说:它可以最大化包含它“2:21,5:50,4:55,7:80,9:33”中存在的所有键2,5,4,7,9,或者它可以“2:21,5:50,4:55”,但键将来自(2,5,4,7,9)的子集。如果未找到任何键,则相应的列应为空字符串无论如何,您可以使用类似的方法,如
charindex()
substring()
提取所需的键和值@Vitaly Borisov:great try..但如果任何键缺少其目标列的插入空值,但我希望它为空字符串,我已根据要求更新了答案,但我强烈建议使用正确的类型(int)而不是到处都是字符串。@Vitaly Borisov:我只是尝试将其扩展为DeviceCurrentMiscercrossBoundaryBurVersion而不是[DeviceMIS BURVersion],DeviceFutureMiscercrossBoundaryBurVersion而不是[FutureMIS BURVersion],等等作为输出列。关于这方面的任何帮助只需替换为select语句@Vitaly Borisov中的[AnyName You need]:如果我们有日期格式i,即:“2017年6月2日,2014年2月3日,11日”尝试单击,但收到:感谢反馈!声誉低于15的人所投的票将被记录,但不会更改公开显示的帖子分数。@Vitaly Borisov:很好的尝试..但是如果任何键缺少其在目标列中插入空值,但我希望它为空字符串,我已根据要求更新了答案,但我强烈建议使用正确的类型(int)而不是到处都是字符串。@Vitaly Borisov:我只是尝试将其扩展为设备当前MiscercrossBoundaryBurversion而不是[DeviceMIS BURVersion],设备未来MiscercrossBoundaryBurversion而不是[FutureMIS BURVersion],以此类推作为输出