我有一张这样的table
Value String-------------------1 Cleo, Smith
Value String
-------------------
1 Cleo, Smith
我想把逗号分隔的字符串分成两列
Value Name Surname-------------------1 Cleo Smith
Value Name Surname
1 Cleo Smith
我只需要两个固定的额外柱子
4dc9hkyq1#
问题很简单,但问题很热门:)所以我为string\u split()创建了一些 Package 器,它以更一般的方式产生pivot结果。它是一个返回值的表函数(nn,value1,value2,值50)-对于大多数csv行足够了。如果有更多的值,它们将换行到下一行-nn表示行号。将第三个参数@columncnt=[yournumber]设置为在特定位置换行:
alter FUNCTION fn_Split50( @str varchar(max), @delim char(1), @columnCnt int = 50)RETURNS TABLE ASRETURN ( SELECT * FROM (SELECT nn = (nn - 1) / @columnCnt + 1, nnn = 'value' + cast(((nn - 1) % @columnCnt) + 1 as varchar(10)), value FROM (SELECT nn = ROW_NUMBER() over (order by (select null)), value FROM string_split(@str, @delim) aa ) aa where nn > 0 ) bb PIVOT ( max(value) FOR nnn IN ( value1, value2, value3, value4, value5, value6, value7, value8, value9, value10, value11, value12, value13, value14, value15, value16, value17, value18, value19, value20, value21, value22, value23, value24, value25, value26, value27, value28, value29, value30, value31, value32, value33, value34, value35, value36, value37, value38, value39, value40, value41, value42, value43, value44, value45, value46, value47, value48, value49, value50 ) ) AS PivotTable )
alter FUNCTION fn_Split50
(
@str varchar(max),
@delim char(1),
@columnCnt int = 50
)
RETURNS TABLE
AS
RETURN
SELECT *
FROM (SELECT
nn = (nn - 1) / @columnCnt + 1,
nnn = 'value' + cast(((nn - 1) % @columnCnt) + 1 as varchar(10)),
value
nn = ROW_NUMBER() over (order by (select null)),
FROM string_split(@str, @delim) aa
) aa
where nn > 0
) bb
PIVOT
max(value)
FOR nnn IN (
value1, value2, value3, value4, value5, value6, value7, value8, value9, value10,
value11, value12, value13, value14, value15, value16, value17, value18, value19, value20,
value21, value22, value23, value24, value25, value26, value27, value28, value29, value30,
value31, value32, value33, value34, value35, value36, value37, value38, value39, value40,
value41, value42, value43, value44, value45, value46, value47, value48, value49, value50
) AS PivotTable
使用示例:
select * from dbo.fn_split50('zz1,aa2,ss3,dd4,ff5', ',', DEFAULT)
select * from dbo.fn_split50('zz1,aa2,ss3,dd4,ff5,gg6,hh7,jj8,ww9,qq10', ',', 3)
select * from dbo.fn_split50('zz1,11,aa2,22,ss3,33,dd4,44,ff5,55,gg6,66,hh7,77,jj8,88,ww9,99,qq10,1010', ',',2)
希望能有所帮助:)
r1zhe5dt2#
我在上面重新写了一个答案,让它变得更好:
CREATE FUNCTION [dbo].[CSVParser]( @s VARCHAR(255), @idx NUMERIC)RETURNS VARCHAR(12)BEGIN DECLARE @comma int SET @comma = CHARINDEX(',', @s) WHILE 1=1 BEGIN IF @comma=0 IF @idx=1 RETURN @s ELSE RETURN '' IF @idx=1 BEGIN DECLARE @word VARCHAR(12) SET @word=LEFT(@s, @comma - 1) RETURN @word END SET @s = RIGHT(@s,LEN(@s)-@comma) SET @comma = CHARINDEX(',', @s) SET @idx = @idx - 1 END RETURN 'not used'END
CREATE FUNCTION [dbo].[CSVParser]
@s VARCHAR(255),
@idx NUMERIC
RETURNS VARCHAR(12)
BEGIN
DECLARE @comma int
SET @comma = CHARINDEX(',', @s)
WHILE 1=1
IF @comma=0
IF @idx=1
RETURN @s
ELSE
RETURN ''
DECLARE @word VARCHAR(12)
SET @word=LEFT(@s, @comma - 1)
RETURN @word
END
SET @s = RIGHT(@s,LEN(@s)-@comma)
SET @idx = @idx - 1
RETURN 'not used'
用法示例:
SELECT dbo.CSVParser(COLUMN, 1), dbo.CSVParser(COLUMN, 2), dbo.CSVParser(COLUMN, 3)FROM TABLE
SELECT dbo.CSVParser(COLUMN, 1),
dbo.CSVParser(COLUMN, 2),
dbo.CSVParser(COLUMN, 3)
FROM TABLE
ne5o7dgx3#
Select distinct PROJ_UID,PROJ_NAME,RES_UID from E2E_ProjectWiseTimesheetActualswhere CHARINDEX(','+cast(PROJ_UID as varchar(8000))+',', @params) > 0 and CHARINDEX(','+cast(RES_UID as varchar(8000))+',', @res) > 0
Select distinct PROJ_UID,PROJ_NAME,RES_UID from E2E_ProjectWiseTimesheetActuals
where CHARINDEX(','+cast(PROJ_UID as varchar(8000))+',', @params) > 0 and CHARINDEX(','+cast(RES_UID as varchar(8000))+',', @res) > 0
uqzxnwby4#
select distinct modelFileId,F4.*from contractcross apply (select XmlList=convert(xml, '<x>'+replace(modelFileId,';','</x><x>')+'</x>').query('.')) F2cross apply (select mfid1=XmlNode.value('/x[1]','varchar(512)'),mfid2=XmlNode.value('/x[2]','varchar(512)'),mfid3=XmlNode.value('/x[3]','varchar(512)'),mfid4=XmlNode.value('/x[4]','varchar(512)') from XmlList.nodes('x') F3(XmlNode)) F4where modelFileId like '%;%'order by modelFileId
select distinct modelFileId,F4.*
from contract
cross apply (select XmlList=convert(xml, '<x>'+replace(modelFileId,';','</x><x>')+'</x>').query('.')) F2
cross apply (select mfid1=XmlNode.value('/x[1]','varchar(512)')
,mfid2=XmlNode.value('/x[2]','varchar(512)')
,mfid3=XmlNode.value('/x[3]','varchar(512)')
,mfid4=XmlNode.value('/x[4]','varchar(512)') from XmlList.nodes('x') F3(XmlNode)) F4
where modelFileId like '%;%'
order by modelFileId
suzh9iv85#
我发现如上所述使用parsename会导致任何带有句点的名称为空。因此,如果名称中有一个首字母或标题后跟一个点,则返回null。我发现这对我有用:
SELECT REPLACE(SUBSTRING(FullName, 1,CHARINDEX(',', FullName)), ',','') as Name,REPLACE(SUBSTRING(FullName, CHARINDEX(',', FullName), LEN(FullName)), ',', '') as SurnameFROM Table1
SELECT
REPLACE(SUBSTRING(FullName, 1,CHARINDEX(',', FullName)), ',','') as Name,
REPLACE(SUBSTRING(FullName, CHARINDEX(',', FullName), LEN(FullName)), ',', '') as Surname
FROM Table1
vd2z7a6w6#
ALTER function get_occurance_index(@delimiter varchar(1),@occurence int,@String varchar(100))returns intAS Begin--Declare @delimiter varchar(1)=',',@occurence int=2,@String varchar(100)='a,b,c'Declare @result int ;with T as ( select 1 Rno,0 as row, charindex(@delimiter, @String) pos,@String st union all select Rno+1,pos + 1, charindex(@delimiter, @String, pos + 1), @String from T where pos > 0)select @result=pos from T where pos > 0 and rno = @occurence return isnull(@result,0)ENddeclare @data as table (data varchar(100))insert into @data values('1,2,3') insert into @data values('aaa,bbbbb,cccc') select top 3 Substring (data,0,dbo.get_occurance_index( ',',1,data)) ,--First Record always starts with 0Substring (data,dbo.get_occurance_index( ',',1,data)+1,dbo.get_occurance_index( ',',2,data)-dbo.get_occurance_index( ',',1,data)-1) ,Substring (data,dbo.get_occurance_index( ',',2,data)+1,len(data)) , -- Last record cant be more than len of actual datadata From @data
ALTER function get_occurance_index(@delimiter varchar(1),@occurence int,@String varchar(100))
returns int
AS Begin
--Declare @delimiter varchar(1)=',',@occurence int=2,@String varchar(100)='a,b,c'
Declare @result int
;with T as (
select 1 Rno,0 as row, charindex(@delimiter, @String) pos,@String st
union all
select Rno+1,pos + 1, charindex(@delimiter, @String, pos + 1), @String
from T
where pos > 0
select @result=pos
where pos > 0 and rno = @occurence
return isnull(@result,0)
ENd
declare @data as table (data varchar(100))
insert into @data values('1,2,3')
insert into @data values('aaa,bbbbb,cccc')
select top 3 Substring (data,0,dbo.get_occurance_index( ',',1,data)) ,--First Record always starts with 0
Substring (data,dbo.get_occurance_index( ',',1,data)+1,dbo.get_occurance_index( ',',2,data)-dbo.get_occurance_index( ',',1,data)-1) ,
Substring (data,dbo.get_occurance_index( ',',2,data)+1,len(data)) , -- Last record cant be more than len of actual data
data
From @data
mrphzbgm7#
您可能会发现在sql用户定义函数中解析分隔字符串的解决方案很有帮助(来自代码项目)。这是本页的代码部分:
CREATE FUNCTION [fn_ParseText2Table] (@p_SourceText VARCHAR(MAX) ,@p_Delimeter VARCHAR(100)=',' --default to comma delimited. ) RETURNS @retTable TABLE([Position] INT IDENTITY(1,1) ,[Int_Value] INT ,[Num_Value] NUMERIC(18,3) ,[Txt_Value] VARCHAR(MAX) ,[Date_value] DATETIME )AS/*********************************************************************************Purpose: Parse values from a delimited string & return the result as an indexed tableCopyright 1996, 1997, 2000, 2003 Clayton Groom (<A href="mailto:Clayton_Groom@hotmail.com">Clayton_Groom@hotmail.com</A>)Posted to the public domain Aug, 20042003-06-17 Rewritten as SQL 2000 function. Reworked to allow for delimiters > 1 character in length and to convert Text values to numbers2016-04-05 Added logic for date values based on "new" ISDATE() function, Updated to use XML approach, which is more efficient.********************************************************************************* /BEGIN DECLARE @w_xml xml; SET @w_xml = N'<root><i>' + replace(@p_SourceText, @p_Delimeter,'</i><i>') + '</i></root>'; INSERT INTO @retTable ([Int_Value] , [Num_Value] , [Txt_Value] , [Date_value] ) SELECT CASE WHEN ISNUMERIC([i].value('.', 'VARCHAR(MAX)')) = 1 THEN CAST(CAST([i].value('.', 'VARCHAR(MAX)') AS NUMERIC) AS INT) END AS [Int_Value] , CASE WHEN ISNUMERIC([i].value('.', 'VARCHAR(MAX)')) = 1 THEN CAST([i].value('.', 'VARCHAR(MAX)') AS NUMERIC(18, 3)) END AS [Num_Value] , [i].value('.', 'VARCHAR(MAX)') AS [txt_Value] , CASE WHEN ISDATE([i].value('.', 'VARCHAR(MAX)')) = 1 THEN CAST([i].value('.', 'VARCHAR(MAX)') AS DATETIME) END AS [Num_Value] FROM @w_xml.nodes('//root/i') AS [Items]([i]); RETURN;END;GO
CREATE FUNCTION [fn_ParseText2Table]
(@p_SourceText VARCHAR(MAX)
,@p_Delimeter VARCHAR(100)=',' --default to comma delimited.
RETURNS @retTable
TABLE([Position] INT IDENTITY(1,1)
,[Int_Value] INT
,[Num_Value] NUMERIC(18,3)
,[Txt_Value] VARCHAR(MAX)
,[Date_value] DATETIME
/*
********************************************************************************
Purpose: Parse values from a delimited string
& return the result as an indexed table
Copyright 1996, 1997, 2000, 2003 Clayton Groom (<A href="mailto:Clayton_Groom@hotmail.com">Clayton_Groom@hotmail.com</A>)
Posted to the public domain Aug, 2004
2003-06-17 Rewritten as SQL 2000 function.
Reworked to allow for delimiters > 1 character in length
and to convert Text values to numbers
2016-04-05 Added logic for date values based on "new" ISDATE() function, Updated to use XML approach, which is more efficient.
* /
DECLARE @w_xml xml;
SET @w_xml = N'<root><i>' + replace(@p_SourceText, @p_Delimeter,'</i><i>') + '</i></root>';
INSERT INTO @retTable
([Int_Value]
, [Num_Value]
, [Txt_Value]
, [Date_value]
SELECT CASE
WHEN ISNUMERIC([i].value('.', 'VARCHAR(MAX)')) = 1
THEN CAST(CAST([i].value('.', 'VARCHAR(MAX)') AS NUMERIC) AS INT)
END AS [Int_Value]
, CASE
THEN CAST([i].value('.', 'VARCHAR(MAX)') AS NUMERIC(18, 3))
END AS [Num_Value]
, [i].value('.', 'VARCHAR(MAX)') AS [txt_Value]
WHEN ISDATE([i].value('.', 'VARCHAR(MAX)')) = 1
THEN CAST([i].value('.', 'VARCHAR(MAX)') AS DATETIME)
FROM @w_xml.nodes('//root/i') AS [Items]([i]);
RETURN;
END;
GO
798qvoo88#
DECLARE @INPUT VARCHAR (MAX)='N,A,R,E,N,D,R,A'DECLARE @ELIMINATE_CHAR CHAR (1)=','DECLARE @L_START INT=1DECLARE @L_END INT=(SELECT LEN (@INPUT))DECLARE @OUTPUT CHAR (1)WHILE @L_START <=@L_ENDBEGIN SET @OUTPUT=(SUBSTRING (@INPUT,@L_START,1)) IF @OUTPUT!=@ELIMINATE_CHAR BEGIN PRINT @OUTPUT END SET @L_START=@L_START+1END
DECLARE @INPUT VARCHAR (MAX)='N,A,R,E,N,D,R,A'
DECLARE @ELIMINATE_CHAR CHAR (1)=','
DECLARE @L_START INT=1
DECLARE @L_END INT=(SELECT LEN (@INPUT))
DECLARE @OUTPUT CHAR (1)
WHILE @L_START <=@L_END
SET @OUTPUT=(SUBSTRING (@INPUT,@L_START,1))
IF @OUTPUT!=@ELIMINATE_CHAR
PRINT @OUTPUT
SET @L_START=@L_START+1
hpxqektj9#
很简单,你可以通过下面的查询:
DECLARE @str NVARCHAR(MAX)='ControlID_05436b78-04ba-9667-fa01-9ff8c1b7c235,3'SELECT LEFT(@str, CHARINDEX(',',@str)-1),RIGHT(@str,LEN(@str)-(CHARINDEX(',',@str)))
DECLARE @str NVARCHAR(MAX)='ControlID_05436b78-04ba-9667-fa01-9ff8c1b7c235,3'
SELECT LEFT(@str, CHARINDEX(',',@str)-1),RIGHT(@str,LEN(@str)-(CHARINDEX(',',@str)))
vlf7wbxs10#
我的表格:
Value ColOne--------------------1 Cleo, Smith
Value ColOne
--------------------
如果没有太多的列,下面的操作应该可以
ALTER TABLE mytable ADD ColTwo nvarchar(256);UPDATE mytable SET ColTwo = LEFT(ColOne, Charindex(',', ColOne) - 1);--'Cleo' = LEFT('Cleo, Smith', Charindex(',', 'Cleo, Smith') - 1)UPDATE mytable SET ColTwo = REPLACE(ColOne, ColTwo + ',', '');--' Smith' = REPLACE('Cleo, Smith', 'Cleo' + ',')UPDATE mytable SET ColOne = REPLACE(ColOne, ',' + ColTwo, ''), ColTwo = LTRIM(ColTwo);--'Cleo' = REPLACE('Cleo, Smith', ',' + ' Smith', '')
ALTER TABLE mytable ADD ColTwo nvarchar(256);
UPDATE mytable SET ColTwo = LEFT(ColOne, Charindex(',', ColOne) - 1);
--'Cleo' = LEFT('Cleo, Smith', Charindex(',', 'Cleo, Smith') - 1)
UPDATE mytable SET ColTwo = REPLACE(ColOne, ColTwo + ',', '');
--' Smith' = REPLACE('Cleo, Smith', 'Cleo' + ',')
UPDATE mytable SET ColOne = REPLACE(ColOne, ',' + ColTwo, ''), ColTwo = LTRIM(ColTwo);
--'Cleo' = REPLACE('Cleo, Smith', ',' + ' Smith', '')
结果:
Value ColOne ColTwo--------------------1 Cleo Smith
Value ColOne ColTwo
tgabmvqs11#
试试这个:
declare @csv varchar(100) ='aaa,bb,csda,daass';set @csv = @csv+',';with cte as( select SUBSTRING(@csv,1,charindex(',',@csv,1)-1) as val, SUBSTRING(@csv,charindex(',',@csv,1)+1,len(@csv)) as rem UNION ALL select SUBSTRING(a.rem,1,charindex(',',a.rem,1)-1)as val, SUBSTRING(a.rem,charindex(',',a.rem,1)+1,len(A.rem)) from cte a where LEN(a.rem)>=1 ) select val from cte
declare @csv varchar(100) ='aaa,bb,csda,daass';
set @csv = @csv+',';
with cte as
select SUBSTRING(@csv,1,charindex(',',@csv,1)-1) as val, SUBSTRING(@csv,charindex(',',@csv,1)+1,len(@csv)) as rem
UNION ALL
select SUBSTRING(a.rem,1,charindex(',',a.rem,1)-1)as val, SUBSTRING(a.rem,charindex(',',a.rem,1)+1,len(A.rem))
from cte a where LEN(a.rem)>=1
) select val from cte
ou6hu8tu12#
这对我有用
CREATE FUNCTION [dbo].[SplitString]( @delimited NVARCHAR(MAX), @delimiter NVARCHAR(100)) RETURNS @t TABLE ( val NVARCHAR(MAX))ASBEGIN DECLARE @xml XML SET @xml = N'<t>' + REPLACE(@delimited,@delimiter,'</t><t>') + '</t>' INSERT INTO @t(val) SELECT r.value('.','varchar(MAX)') as item FROM @xml.nodes('/t') as records(r) RETURNEND
CREATE FUNCTION [dbo].[SplitString](
@delimited NVARCHAR(MAX),
@delimiter NVARCHAR(100)
) RETURNS @t TABLE ( val NVARCHAR(MAX))
DECLARE @xml XML
SET @xml = N'<t>' + REPLACE(@delimited,@delimiter,'</t><t>') + '</t>'
INSERT INTO @t(val)
SELECT r.value('.','varchar(MAX)') as item
FROM @xml.nodes('/t') as records(r)
vfhzx4xs13#
使用instring函数:)
select Value, substring(String,1,instr(String," ") -1) Fname, substring(String,instr(String,",") +1) Sname from tablename;
select Value,
substring(String,1,instr(String," ") -1) Fname,
substring(String,instr(String,",") +1) Sname
from tablename;
使用了两种功能,
substring(string, position, length)
instr(string,pattern)
hm2xizp914#
我遇到了一个类似的问题,但一个复杂的一个,因为这是第一个线程,我发现关于这个问题,我决定张贴我的发现。我知道这是一个简单问题的复杂解决方案,但我希望我可以帮助其他人谁去寻找一个更复杂的解决方案这个线程。我不得不拆分一个包含5个数字(列名:levelsfeed)的字符串,并在单独的列中显示每个数字。例如:8,1,2,2,2应显示为:
1 2 3 4 5-------------8 1 2 2 2
1 2 3 4 5
-------------
8 1 2 2 2
解决方案1:使用xml函数:这是迄今为止最慢的解决方案
SELECT Distinct FeedbackID, , S.a.value('(/H/r)[1]', 'INT') AS level1, S.a.value('(/H/r)[2]', 'INT') AS level2, S.a.value('(/H/r)[3]', 'INT') AS level3, S.a.value('(/H/r)[4]', 'INT') AS level4, S.a.value('(/H/r)[5]', 'INT') AS level5FROM ( SELECT *,CAST (N'<H><r>' + REPLACE(levelsFeed, ',', '</r><r>') + '</r> </H>' AS XML) AS [vals] FROM Feedbacks ) as dCROSS APPLY d.[vals].nodes('/H/r') S(a)
SELECT Distinct FeedbackID,
, S.a.value('(/H/r)[1]', 'INT') AS level1
, S.a.value('(/H/r)[2]', 'INT') AS level2
, S.a.value('(/H/r)[3]', 'INT') AS level3
, S.a.value('(/H/r)[4]', 'INT') AS level4
, S.a.value('(/H/r)[5]', 'INT') AS level5
FROM (
SELECT *,CAST (N'<H><r>' + REPLACE(levelsFeed, ',', '</r><r>') + '</r> </H>' AS XML) AS [vals]
FROM Feedbacks
) as d
CROSS APPLY d.[vals].nodes('/H/r') S(a)
解决方案2:使用split函数和pivot(split函数将字符串拆分为具有列名(data)的行
SELECT FeedbackID, [1],[2],[3],[4],[5]FROM ( SELECT *, ROW_NUMBER() OVER (PARTITION BY feedbackID ORDER BY (SELECT null)) as rn FROM ( SELECT FeedbackID, levelsFeed FROM Feedbacks ) as aCROSS APPLY dbo.Split(levelsFeed, ',')) as SourceTablePIVOT( MAX(data) FOR rn IN ([1],[2],[3],[4],[5]))as pivotTable
SELECT FeedbackID, [1],[2],[3],[4],[5]
SELECT *, ROW_NUMBER() OVER (PARTITION BY feedbackID ORDER BY (SELECT null)) as rn
SELECT FeedbackID, levelsFeed
) as a
CROSS APPLY dbo.Split(levelsFeed, ',')
) as SourceTable
MAX(data)
FOR rn IN ([1],[2],[3],[4],[5])
)as pivotTable
解决方案3:使用字符串操作函数-比解决方案2更快
SELECT FeedbackID,SUBSTRING(levelsFeed,0,CHARINDEX(',',levelsFeed)) AS level1,PARSENAME(REPLACE(SUBSTRING(levelsFeed,CHARINDEX(',',levelsFeed)+1,LEN(levelsFeed)),',','.'),4) AS level2,PARSENAME(REPLACE(SUBSTRING(levelsFeed,CHARINDEX(',',levelsFeed)+1,LEN(levelsFeed)),',','.'),3) AS level3,PARSENAME(REPLACE(SUBSTRING(levelsFeed,CHARINDEX(',',levelsFeed)+1,LEN(levelsFeed)),',','.'),2) AS level4,PARSENAME(REPLACE(SUBSTRING(levelsFeed,CHARINDEX(',',levelsFeed)+1,LEN(levelsFeed)),',','.'),1) AS level5FROM Feedbacks
SELECT FeedbackID,
SUBSTRING(levelsFeed,0,CHARINDEX(',',levelsFeed)) AS level1,
PARSENAME(REPLACE(SUBSTRING(levelsFeed,CHARINDEX(',',levelsFeed)+1,LEN(levelsFeed)),',','.'),4) AS level2,
PARSENAME(REPLACE(SUBSTRING(levelsFeed,CHARINDEX(',',levelsFeed)+1,LEN(levelsFeed)),',','.'),3) AS level3,
PARSENAME(REPLACE(SUBSTRING(levelsFeed,CHARINDEX(',',levelsFeed)+1,LEN(levelsFeed)),',','.'),2) AS level4,
PARSENAME(REPLACE(SUBSTRING(levelsFeed,CHARINDEX(',',levelsFeed)+1,LEN(levelsFeed)),',','.'),1) AS level5
因为levelsfeed包含5个字符串值,所以我需要对第一个字符串使用substring函数。我希望我的解决方案能帮助其他人找到更复杂的拆分为列的方法
a0zr77ik15#
此功能最快:
CREATE FUNCTION dbo.F_ExtractSubString( @String VARCHAR(MAX), @NroSubString INT, @Separator VARCHAR(5))RETURNS VARCHAR(MAX) ASBEGIN DECLARE @St INT = 0, @End INT = 0, @Ret VARCHAR(MAX) SET @String = @String + @Separator WHILE CHARINDEX(@Separator, @String, @End + 1) > 0 AND @NroSubString > 0 BEGIN SET @St = @End + 1 SET @End = CHARINDEX(@Separator, @String, @End + 1) SET @NroSubString = @NroSubString - 1 END IF @NroSubString > 0 SET @Ret = '' ELSE SET @Ret = SUBSTRING(@String, @St, @End - @St) RETURN @RetENDGO
CREATE FUNCTION dbo.F_ExtractSubString
@String VARCHAR(MAX),
@NroSubString INT,
@Separator VARCHAR(5)
RETURNS VARCHAR(MAX) AS
DECLARE @St INT = 0, @End INT = 0, @Ret VARCHAR(MAX)
SET @String = @String + @Separator
WHILE CHARINDEX(@Separator, @String, @End + 1) > 0 AND @NroSubString > 0
SET @St = @End + 1
SET @End = CHARINDEX(@Separator, @String, @End + 1)
SET @NroSubString = @NroSubString - 1
IF @NroSubString > 0
SET @Ret = ''
SET @Ret = SUBSTRING(@String, @St, @End - @St)
RETURN @Ret
SELECT dbo.F_ExtractSubString(COLUMN, 1, ', '), dbo.F_ExtractSubString(COLUMN, 2, ', '), dbo.F_ExtractSubString(COLUMN, 3, ', ')FROM TABLE
SELECT dbo.F_ExtractSubString(COLUMN, 1, ', '),
dbo.F_ExtractSubString(COLUMN, 2, ', '),
dbo.F_ExtractSubString(COLUMN, 3, ', ')
30条答案
按热度按时间4dc9hkyq1#
问题很简单,但问题很热门:)
所以我为string\u split()创建了一些 Package 器,它以更一般的方式产生pivot结果。它是一个返回值的表函数(nn,value1,value2,值50)-对于大多数csv行足够了。如果有更多的值,它们将换行到下一行-nn表示行号。将第三个参数@columncnt=[yournumber]设置为在特定位置换行:
使用示例:
希望能有所帮助:)
r1zhe5dt2#
我在上面重新写了一个答案,让它变得更好:
用法示例:
ne5o7dgx3#
uqzxnwby4#
suzh9iv85#
我发现如上所述使用parsename会导致任何带有句点的名称为空。
因此,如果名称中有一个首字母或标题后跟一个点,则返回null。
我发现这对我有用:
vd2z7a6w6#
mrphzbgm7#
您可能会发现在sql用户定义函数中解析分隔字符串的解决方案很有帮助(来自代码项目)。
这是本页的代码部分:
798qvoo88#
hpxqektj9#
很简单,你可以通过下面的查询:
vlf7wbxs10#
我的表格:
如果没有太多的列,下面的操作应该可以
结果:
tgabmvqs11#
试试这个:
ou6hu8tu12#
这对我有用
vfhzx4xs13#
使用instring函数:)
使用了两种功能,
substring(string, position, length)
==>返回从位置到长度的字符串instr(string,pattern)
==>返回图案的位置。如果我们在子字符串中不提供长度参数,它将返回到字符串的末尾
hm2xizp914#
我遇到了一个类似的问题,但一个复杂的一个,因为这是第一个线程,我发现关于这个问题,我决定张贴我的发现。我知道这是一个简单问题的复杂解决方案,但我希望我可以帮助其他人谁去寻找一个更复杂的解决方案这个线程。我不得不拆分一个包含5个数字(列名:levelsfeed)的字符串,并在单独的列中显示每个数字。例如:8,1,2,2,2应显示为:
解决方案1:使用xml函数:这是迄今为止最慢的解决方案
解决方案2:使用split函数和pivot(split函数将字符串拆分为具有列名(data)的行
解决方案3:使用字符串操作函数-比解决方案2更快
因为levelsfeed包含5个字符串值,所以我需要对第一个字符串使用substring函数。
我希望我的解决方案能帮助其他人找到更复杂的拆分为列的方法
a0zr77ik15#
此功能最快:
用法示例: