我有一个场景,我希望将数据从冒号分割为新列。
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
有谁能告诉我如何实现这个目标?任何帮助将不胜感激。
答案 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
循环在每个;
之前拆分每个部分。然后使用LEFT
和RIGHT
函数从分割部分中获取:
之前和之后的部分。并将这些值插入表变量@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