将数据从冒号拆分为新列

时间:2018-04-20 07:58:32

标签: sql sql-server

我有一个场景,我希望将数据从冒号分割为新列。 E.g YR:136;YR:50;JN:275;YM:138;IN:477;WO:150;G1:10;F2:10

我正在寻找的是:

YR  136
YR   50
JN   275
YM   138

有谁能告诉我如何实现这个目标?任何帮助将不胜感激。

6 个答案:

答案 0 :(得分:2)

对于SQL 2016及更高版本,您可以使用STRING_SPLIT。如果没有,请搜索CSV Spliter

declare @str varchar(100) = 'YR:136;YR:50;JN:275;YM:138;IN:477;WO:150;G1:10;F2:10'

select  parsename(replace(value, ':', '.'), 2),
        parsename(replace(value, ':', '.'), 1)
from    string_split(@str, ';')

答案 1 :(得分:1)

希望字符串每次都以指定的格式显示。我做的是,首先将相同的字符串复制到一个新变量,并在末尾添加一个额外的;。然后使用WHILE循环在每个;之前拆分每个部分。然后使用LEFTRIGHT函数从分割部分中获取:之前和之后的部分。并将这些值插入表变量@t

<强>代码

declare @str as varchar(max) ='YR:136;YR:50;JN:275;YM:138;IN:477;WO:150;G1:10;F2:10';

declare @rows as int;
set @rows = len(@str) - len(replace(@str, ';',''));

declare @t as table([col1] varchar(100), [col2] int);

declare @i as int;
set @i = 0;

declare @str2 as varchar(max);
set @str2 = @str + ';';

while(@i <= @rows)
begin
    declare @col as varchar(100);
    set @col = left(@str2, charindex(';', @str2, 1) - 1);
    set @str2 = right(@str2, len(@str2) - charindex(';', @str2, 1));    
    insert into @t([col1], [col2])
    select 
        left(@col, charindex(':', @col, 1) - 1), 
        right(@col, charindex(':', reverse(@col), 1) - 1);
    set @i += 1;
end

select * from @t;

<强> Find a demo here

答案 2 :(得分:0)

在SQL Server中,您可以使用STRING_SPLIT

执行此操作

有关更多信息,请阅读文档: https://docs.microsoft.com/en-us/sql/t-sql/functions/string-split-transact-sql?view=sql-server-2017

答案 3 :(得分:0)

首先创建函数:

CREATE FUNCTION dbo.fnSplit(
    @sInputList VARCHAR(8000) -- List of delimited items
  , @sDelimiter VARCHAR(8000) = ',' -- delimiter that separates items
) RETURNS @List TABLE (item VARCHAR(8000))

BEGIN
DECLARE @sItem VARCHAR(8000)
WHILE CHARINDEX(@sDelimiter,@sInputList,0) <> 0
 BEGIN
 SELECT
  @sItem=RTRIM(LTRIM(SUBSTRING(@sInputList,1,CHARINDEX(@sDelimiter,@sInputList,0)-1))),
  @sInputList=RTRIM(LTRIM(SUBSTRING(@sInputList,CHARINDEX(@sDelimiter,@sInputList,0)+LEN(@sDelimiter),LEN(@sInputList))))

 IF LEN(@sItem) > 0
  INSERT INTO @List SELECT @sItem
 END

IF LEN(@sInputList) > 0
 INSERT INTO @List SELECT @sInputList -- Put the last item in
RETURN
END
GO

然后试试这个:

DECLARE @X VARCHAR(100), @Val VARCHAR(250) = 'YR:136;YR:50;JN:275;YM:138;IN:477;WO:150;G1:10;F2:10'

SELECT LEFT(value,CHARINDEX(':',value) - 1)A
    ,RIGHT(value,CHARINDEX(':',REVERSE(value)) - 1)B
FROM dbo.fn_Split(@Val,';')

<强>输出:

A   B
YR  136
YR  50
JN  275
YM  138
IN  477
WO  150
G1  10
F2  10

答案 4 :(得分:0)

- FOR SQL SERVER 2016 +

DECLARE @str VARCHAR(100) = 'YR:136;YR:50;JN:275;YM:138;IN:477;WO:150;G1:10;F2:10'

SELECT    SUBSTRING(value,0,CHARINDEX(':',value,0)) Id 
        , SUBSTRING(value,CHARINDEX(':',value,0)+1,100) Vals
FROM    STRING_SPLIT(@str, ';')

- 适用于较旧的SQL SERVER

DECLARE @x AS XML=''
SET @x = CAST('<A>'+ REPLACE(@str,';','</A><A>')+ '</A>' AS XML)
SELECT SUBSTRING(t.value('.', 'VARCHAR(MAX)') ,0,CHARINDEX(':',t.value('.', 'VARCHAR(MAX)') ,0)) Id  
     , SUBSTRING(t.value('.', 'VARCHAR(MAX)') ,CHARINDEX(':',t.value('.', 'VARCHAR(MAX)') ,0)+1,100) Vals
FROM @x.nodes('/A') AS x(t)

答案 5 :(得分:0)

尝试以下功能

CREATE FUNCTION [dbo].[udf_GetUnsplitGivenData]
(
@string nvarchar(max)
)
RETURNS  @OutTable TABLE
(
COl1 nvarchar(max),
COl2 nvarchar(max)
)
AS
BEGIN

    DECLARE @Temp AS TABLE
    (
    DATA nvarchar(max)
    )
    INSERT INTO @Temp
    SELECT @string


    INSERT INTO @OutTable(COl1,COl2)
    SELECT  SUBSTRING(Data,1,CHARINDEX(':',Data )-1) AS COl1,
            SUBSTRING(Data,CHARINDEX(':',Data )+1,LEN(Data)) AS COl2
    FROM
    (
    SELECT  Split.a.value('.','nvarchar(100)') AS Data 
    FROM
    (
    SELECT 
    CAST( '<S>'+REPLACE(Data,';','</S><S>')+'</S>' AS XML ) AS Data 
    FROM @Temp
    ) AS A
    CROSS APPLY data.nodes('S') AS Split(a)
    )dt


RETURN
END
SELECT * FROM [dbo].[udf_GetUnsplitGivenData] (
  'YR:136;YR:50;JN:275;YM:138;IN:477;WO:150;G1:10;F2:10')
GO

结果

COl1    COl2
------------
YR      136
YR      50
JN      275
YM      138
IN      477
WO      150
G1      10
F2      10