[SQL] 내가 항목 X에 액세스 할 수 있도록 어떻게 문자열을 분할합니까?
SQL내가 항목 X에 액세스 할 수 있도록 어떻게 문자열을 분할합니까?
내가 항목 X에 액세스 할 수 있도록 내가 문자열을 분할 어떻게, SQL Server를 사용?
문자열 "안녕하세요 존 스미스"를보십시오. 어떻게 "존"을 반환해야합니다 공간 및 액세스 인덱스 1의 항목으로 문자열을 분할 할 수 있습니다?
해결법
-
==============================
1.있습니다 (코드 프로젝트에서) 도움이 구분 된 문자열 구문 분석에 SQL 사용자 정의 함수에서 솔루션을 찾을 수 있습니다.
있습니다 (코드 프로젝트에서) 도움이 구분 된 문자열 구문 분석에 SQL 사용자 정의 함수에서 솔루션을 찾을 수 있습니다.
이 간단한 논리를 사용할 수 있습니다 :
Declare @products varchar(200) = '1|20|3|343|44|6|8765' Declare @individual varchar(20) = null WHILE LEN(@products) > 0 BEGIN IF PATINDEX('%|%', @products) > 0 BEGIN SET @individual = SUBSTRING(@products, 0, PATINDEX('%|%', @products)) SELECT @individual SET @products = SUBSTRING(@products, LEN(@individual + '|') + 1, LEN(@products)) END ELSE BEGIN SET @individual = @products SET @products = NULL SELECT @individual END END
-
==============================
2.나는 SQL Server가 UDF보다 내장 분할 기능, 그래서 다른 가지고 있다고 생각하지 않는다, 내가 아는 유일한 대답은 PARSENAME 기능을 납치하는 것입니다 :
나는 SQL Server가 UDF보다 내장 분할 기능, 그래서 다른 가지고 있다고 생각하지 않는다, 내가 아는 유일한 대답은 PARSENAME 기능을 납치하는 것입니다 :
SELECT PARSENAME(REPLACE('Hello John Smith', ' ', '.'), 2)
PARSENAME는 문자열을 받아 기간 문자에 분할합니다. 이것은 두 번째 인수로서 숫자를 취하고, 반환 할 문자열의 개수를 지정하는 것을 세그먼트 (정면에서 위로 작동).
SELECT PARSENAME(REPLACE('Hello John Smith', ' ', '.'), 3) --return Hello
문자열이 이미 기간이 포함 된 경우 명백한 문제입니다. 난 여전히 UDF를 사용하여 ... 다른 제안을하는 가장 좋은 방법이라고 생각?
-
==============================
3.첫째, 함수 생성 (CTE를 사용하여, 공통 테이블 표현식은 임시 테이블에 대한 필요성 페지)
첫째, 함수 생성 (CTE를 사용하여, 공통 테이블 표현식은 임시 테이블에 대한 필요성 페지)
create function dbo.SplitString ( @str nvarchar(4000), @separator char(1) ) returns table AS return ( with tokens(p, a, b) AS ( select 1, 1, charindex(@separator, @str) union all select p + 1, b + 1, charindex(@separator, @str, b + 1) from tokens where b > 0 ) select p-1 zeroBasedOccurance, substring( @str, a, case when b > 0 then b-a ELSE 4000 end) AS s from tokens ) GO
그런 다음, 모든 테이블로 사용 (또는 기존 저장된 프로 시저에 맞도록 수정)이있다.
select s from dbo.SplitString('Hello John Smith', ' ') where zeroBasedOccurance=1
최신 정보
이전 버전은 4000 개 문자보다 긴 입력 문자열을 실패합니다. 이 버전은 제한을 처리합니다 :
create function dbo.SplitString ( @str nvarchar(max), @separator char(1) ) returns table AS return ( with tokens(p, a, b) AS ( select cast(1 as bigint), cast(1 as bigint), charindex(@separator, @str) union all select p + 1, b + 1, charindex(@separator, @str, b + 1) from tokens where b > 0 ) select p-1 ItemIndex, substring( @str, a, case when b > 0 then b-a ELSE LEN(@str) end) AS s from tokens ); GO
사용법은 동일하게 유지됩니다.
-
==============================
4.솔루션의 대부분은 여기에있는 동안 루프 또는 재귀 CTE를 사용합니다. 세트 기반의 접근 방식은 공간보다 구분자 기타를 사용할 수 있는지 나는, 약속, 우수한 될 것입니다 :
솔루션의 대부분은 여기에있는 동안 루프 또는 재귀 CTE를 사용합니다. 세트 기반의 접근 방식은 공간보다 구분자 기타를 사용할 수 있는지 나는, 약속, 우수한 될 것입니다 :
CREATE FUNCTION [dbo].[SplitString] ( @List NVARCHAR(MAX), @Delim VARCHAR(255) ) RETURNS TABLE AS RETURN ( SELECT [Value], idx = RANK() OVER (ORDER BY n) FROM ( SELECT n = Number, [Value] = LTRIM(RTRIM(SUBSTRING(@List, [Number], CHARINDEX(@Delim, @List + @Delim, [Number]) - [Number]))) FROM (SELECT Number = ROW_NUMBER() OVER (ORDER BY name) FROM sys.all_objects) AS x WHERE Number <= LEN(@List) AND SUBSTRING(@Delim + @List, [Number], LEN(@Delim)) = @Delim ) AS y );
샘플 사용 :
SELECT Value FROM dbo.SplitString('foo,bar,blat,foo,splunge',',') WHERE idx = 3;
결과 :
---- blat
당신은 또한 당신이 함수에 인수로 원하는 IDX을 추가 할 수 있습니다, 그러나 나는 독자에게 연습으로 떠날 것이다.
더 분할 기능, 왜 (그리고 증거가)에 분할 문자열은 애플리케이션 계층에서 오는 경우 루프와 재귀 CTE를하지 스케일, 그리고 더 나은 대안을 수행하는 동안 :
위의 SQL 서버 2016에,하지만 당신은 STRING_SPLIT ()와 STRING_AGG ()를 보라 :
-
==============================
5.당신은 문자열의 구문 분석을 할 수있는 번호 테이블을 활용할 수 있습니다.
당신은 문자열의 구문 분석을 할 수있는 번호 테이블을 활용할 수 있습니다.
실제 숫자 테이블을 작성 :
create table dbo.Numbers (N int primary key); insert into dbo.Numbers select top 1000 row_number() over(order by number) from master..spt_values go
1000000 개 행이 테스트 테이블 만들기
create table #yak (i int identity(1,1) primary key, array varchar(50)) insert into #yak(array) select 'a,b,c' from dbo.Numbers n cross join dbo.Numbers nn go
기능 만들기
create function [dbo].[ufn_ParseArray] ( @Input nvarchar(4000), @Delimiter char(1) = ',', @BaseIdent int ) returns table as return ( select row_number() over (order by n asc) + (@BaseIdent - 1) [i], substring(@Input, n, charindex(@Delimiter, @Input + @Delimiter, n) - n) s from dbo.Numbers where n <= convert(int, len(@Input)) and substring(@Delimiter + @Input, n, 1) = @Delimiter ) go
사용 (내 노트북에 40 대 출력 3mil 행)
select * from #yak cross apply dbo.ufn_ParseArray(array, ',', 1)
대청소
drop table dbo.Numbers; drop function [dbo].[ufn_ParseArray]
여기에 성능은 놀라운 것이 아니라 백만 행 테이블에 함수를 호출하는 것은 좋은 생각이 아니다. 문자열을 수행하는 많은 행에 걸쳐 분할하면 나는 기능을 피할 것이다.
-
==============================
6.이 질문은하지만, n 번째 요소를 얻는 방법에 대한 문자열 분할 방법에 관하여이지 않는다.
이 질문은하지만, n 번째 요소를 얻는 방법에 대한 문자열 분할 방법에 관하여이지 않는다.
여기에 모든 답이 재귀 CTE를 여러 CHARINDEX, REVERSE 및 PATINDEX 함수를 발명을 사용하여 문자열을 분할 어떤 종류의 일을하는, CLR 방법, 숫자 테이블, CROSS 시만에 대한 호출은 ... 대부분의 답변은 많은 코드를 다룹니다.
유형의 안전 : - 당신이 정말로 n 번째 요소를 얻기 위해 더 접근보다는 아무것도하지 않으 - 그러나 이것은 실제 한 줄, 아니 UDF, 심지어 하위이-선택 ... 그리고 추가 혜택 등으로 수행 할 수 있습니다
공백으로 구분 된 2 부 가져 오기 :
DECLARE @input NVARCHAR(100)=N'part1 part2 part3'; SELECT CAST(N'<x>' + REPLACE(@input,N' ',N'</x><x>') + N'</x>' AS XML).value('/x[2]','nvarchar(max)')
물론 당신은 구분 기호와 위치에 대한 변수를 사용할 수 있습니다 (사용 SQL을 : 열을 쿼리의 값에서 직접 위치를 검색하기 위해) :
DECLARE @dlmt NVARCHAR(10)=N' '; DECLARE @pos INT = 2; SELECT CAST(N'<x>' + REPLACE(@input,@dlmt,N'</x><x>') + N'</x>' AS XML).value('/x[sql:variable("@pos")][1]','nvarchar(max)')
당신의 문자열 (> <사이에서 특히 하나) 금지 문자를 포함 할 수 있습니다 경우에도 이런 식으로 할 수 있습니다. 그냥 암시 적으로 피팅 이스케이프 시퀀스 모든 금지 문자를 대체하기 위해 먼저 문자열을 XML 경로 사용합니다.
추가 - -이 경우 아주 특수한 경우의 당신의 구분은 세미콜론입니다. 이 경우 내가 먼저 '#의 DLMT 번호'로 구분 기호를 대체하고, 마지막으로 XML 태그에이 대체 :
SET @input=N'Some <, > and &;Other äöü@€;One more'; SET @dlmt=N';'; SELECT CAST(N'<x>' + REPLACE((SELECT REPLACE(@input,@dlmt,'#DLMT#') AS [*] FOR XML PATH('')),N'#DLMT#',N'</x><x>') + N'</x>' AS XML).value('/x[sql:variable("@pos")][1]','nvarchar(max)');
유감스럽게도 개발자는 STRING_SPLIT와 부분의 인덱스를 반환하는 것을 잊었다. 그러나, SQL-Server를 2016+ 사용 JSON_VALUE 및 OPENJSON있다.
JSON_VALUE으로 우리는 인덱스 '배열과 위치에 전달할 수있다.
OPENJSON에 대한 설명서 명확하게 진술한다 :
1,2,3 같은 문자열은 괄호보다 더 아무것도 필요하지 않습니다 : [1,2,3]. 이와 같은 단어의 문자열 [ "이", "에", "예" "는"일례 필요가있을 것이다. 이들은 매우 쉽게 문자열 연산입니다. 그냥 그것을 밖으로 시도 :
DECLARE @str VARCHAR(100)='Hello John Smith'; DECLARE @position INT = 2; --We can build the json-path '$[1]' using CONCAT SELECT JSON_VALUE('["' + REPLACE(@str,' ','","') + '"]',CONCAT('$[',@position-1,']'));
안전한 위치 문자열 스플리터 (제로로부터) 이것을 다니게 :
SELECT JsonArray.[key] AS [Position] ,JsonArray.[value] AS [Part] FROM OPENJSON('["' + REPLACE(@str,' ','","') + '"]') JsonArray
이 게시물에서 나는 OPENJSON 정말 빠른 것으로, 다양한 방법을 시험하고 발견했다. 심지어 훨씬 더 빨리 유명한 "delimitedSplit8k ()"방법보다 ...
우리는 단순히 배로 []를 사용하여 어레이 내에 배열을 사용할 수있다. 이것은 입력 WITH 절을 허용 :
DECLARE @SomeDelimitedString VARCHAR(100)='part1|1|20190920'; DECLARE @JsonArray NVARCHAR(MAX)=CONCAT('[["',REPLACE(@SomeDelimitedString,'|','","'),'"]]'); SELECT @SomeDelimitedString AS TheOriginal ,@JsonArray AS TransformedToJSON ,ValuesFromTheArray.* FROM OPENJSON(@JsonArray) WITH(TheFirstFragment VARCHAR(100) '$[0]' ,TheSecondFragment INT '$[1]' ,TheThirdFragment DATE '$[2]') ValuesFromTheArray
-
==============================
7.여기에 그것을 할 것 UDF이다. 그것은 구분 된 값의 테이블, 거기에 모든 시나리오를 시도하지 않은하지만 예를 잘 작동 반환합니다.
여기에 그것을 할 것 UDF이다. 그것은 구분 된 값의 테이블, 거기에 모든 시나리오를 시도하지 않은하지만 예를 잘 작동 반환합니다.
CREATE FUNCTION SplitString ( -- Add the parameters for the function here @myString varchar(500), @deliminator varchar(10) ) RETURNS @ReturnTable TABLE ( -- Add the column definitions for the TABLE variable here [id] [int] IDENTITY(1,1) NOT NULL, [part] [varchar](50) NULL ) AS BEGIN Declare @iSpaces int Declare @part varchar(50) --initialize spaces Select @iSpaces = charindex(@deliminator,@myString,0) While @iSpaces > 0 Begin Select @part = substring(@myString,0,charindex(@deliminator,@myString,0)) Insert Into @ReturnTable(part) Select @part Select @myString = substring(@mystring,charindex(@deliminator,@myString,0)+ len(@deliminator),len(@myString) - charindex(' ',@myString,0)) Select @iSpaces = charindex(@deliminator,@myString,0) end If len(@myString) > 0 Insert Into @ReturnTable Select @myString RETURN END GO
당신은 이런 식으로 부를 것이다 :
Select * From SplitString('Hello John Smith',' ')
편집하십시오 LEN> 1과와 핸들 delimters에 업데이트 솔루션 :
select * From SplitString('Hello**John**Smith','**')
-
==============================
8.여기에 내가 솔루션의 간단한 방법을 게시
여기에 내가 솔루션의 간단한 방법을 게시
CREATE FUNCTION [dbo].[split]( @delimited NVARCHAR(MAX), @delimiter NVARCHAR(100) ) RETURNS @t TABLE (id INT IDENTITY(1,1), val NVARCHAR(MAX)) AS BEGIN 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) RETURN END
이 같은 기능을 실행
select * from dbo.split('Hello John Smith',' ')
-
==============================
9.제 생각에는 너희들은 너무 복잡하고 있습니다. 그냥 CLR UDF를 작성하고 함께 할 수.
제 생각에는 너희들은 너무 복잡하고 있습니다. 그냥 CLR UDF를 작성하고 함께 할 수.
using System; using System.Data; using System.Data.SqlClient; using System.Data.SqlTypes; using Microsoft.SqlServer.Server; using System.Collections.Generic; public partial class UserDefinedFunctions { [SqlFunction] public static SqlString SearchString(string Search) { List<string> SearchWords = new List<string>(); foreach (string s in Search.Split(new char[] { ' ' })) { if (!s.ToLower().Equals("or") && !s.ToLower().Equals("and")) { SearchWords.Add(s); } } return new SqlString(string.Join(" OR ", SearchWords.ToArray())); } };
-
==============================
10.무엇 문자열 값 () 문을 사용하는 방법에 대한?
무엇 문자열 값 () 문을 사용하는 방법에 대한?
DECLARE @str varchar(max) SET @str = 'Hello John Smith' DECLARE @separator varchar(max) SET @separator = ' ' DECLARE @Splited TABLE(id int IDENTITY(1,1), item varchar(max)) SET @str = REPLACE(@str, @separator, '''),(''') SET @str = 'SELECT * FROM (VALUES(''' + @str + ''')) AS V(A)' INSERT INTO @Splited EXEC(@str) SELECT * FROM @Splited
달성 결과-설정합니다.
id item 1 Hello 2 John 3 Smith
-
==============================
11.나는 프레드릭의 대답을 사용하지만이 SQL Server 2005에서 작동하지 않았다
나는 프레드릭의 대답을 사용하지만이 SQL Server 2005에서 작동하지 않았다
나는 그것을 수정하고 나는 모든 조합으로 선택 사용하고 있는데 작동
DECLARE @str varchar(max) SET @str = 'Hello John Smith how are you' DECLARE @separator varchar(max) SET @separator = ' ' DECLARE @Splited table(id int IDENTITY(1,1), item varchar(max)) SET @str = REPLACE(@str, @separator, ''' UNION ALL SELECT ''') SET @str = ' SELECT ''' + @str + ''' ' INSERT INTO @Splited EXEC(@str) SELECT * FROM @Splited
그리고 결과 집합은 다음과 같습니다
id item 1 Hello 2 John 3 Smith 4 how 5 are 6 you
-
==============================
12.이 패턴은 잘 작동하고 당신은 일반화 할 수 있습니다
이 패턴은 잘 작동하고 당신은 일반화 할 수 있습니다
Convert(xml,'<n>'+Replace(FIELD,'.','</n><n>')+'</n>').value('(/n[INDEX])','TYPE') ^^^^^ ^^^^^ ^^^^
FIELD, INDEX 및 TYPE을 확인합니다.
같은 식별자 일부 테이블을 보자
sys.message.1234.warning.A45 sys.message.1235.error.O98 ....
그렇다면, 당신은 쓸 수 있습니다
SELECT Source = q.value('(/n[1])', 'varchar(10)'), RecordType = q.value('(/n[2])', 'varchar(20)'), RecordNumber = q.value('(/n[3])', 'int'), Status = q.value('(/n[4])', 'varchar(5)') FROM ( SELECT q = Convert(xml,'<n>'+Replace(fieldName,'.','</n><n>')+'</n>') FROM some_TABLE ) Q
분할 및 모든 부품을 주조.
-
==============================
13.데이터베이스가 130 이상 호환성 수준이있는 경우 당신은 인덱스로 특정 아이템을 얻기 위해 절을 FETCH OFFSET과 함께 STRING_SPLIT 기능을 사용할 수 있습니다.
데이터베이스가 130 이상 호환성 수준이있는 경우 당신은 인덱스로 특정 아이템을 얻기 위해 절을 FETCH OFFSET과 함께 STRING_SPLIT 기능을 사용할 수 있습니다.
인덱스 N (영 기준)에있는 항목을 얻으려면, 다음과 같은 코드를 사용할 수 있습니다
SELECT value FROM STRING_SPLIT('Hello John Smith',' ') ORDER BY (SELECT NULL) OFFSET N ROWS FETCH NEXT 1 ROWS ONLY
데이터베이스의 호환성 수준을 확인하려면이 코드를 실행합니다 :
SELECT compatibility_level FROM sys.databases WHERE name = 'YourDBName';
-
==============================
14.나는 나를 위해 작품 아래의 그물에 솔루션과 찾고 있었다. 참조.
나는 나를 위해 작품 아래의 그물에 솔루션과 찾고 있었다. 참조.
그리고이 같은 함수를 호출 :
SELECT * FROM dbo.split('ram shyam hari gopal',' ')
SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE FUNCTION [dbo].[Split](@String VARCHAR(8000), @Delimiter CHAR(1)) RETURNS @temptable TABLE (items VARCHAR(8000)) AS BEGIN DECLARE @idx INT DECLARE @slice VARCHAR(8000) SELECT @idx = 1 IF len(@String)<1 OR @String IS NULL RETURN WHILE @idx!= 0 BEGIN SET @idx = charindex(@Delimiter,@String) IF @idx!=0 SET @slice = LEFT(@String,@idx - 1) ELSE SET @slice = @String IF(len(@slice)>0) INSERT INTO @temptable(Items) VALUES(@slice) SET @String = RIGHT(@String,len(@String) - @idx) IF len(@String) = 0 break END RETURN END
-
==============================
15.또 다른 구분 기호 기능에 의해 문자열의 n 번째 부분을 얻을 :
또 다른 구분 기호 기능에 의해 문자열의 n 번째 부분을 얻을 :
create function GetStringPartByDelimeter ( @value as nvarchar(max), @delimeter as nvarchar(max), @position as int ) returns NVARCHAR(MAX) AS BEGIN declare @startPos as int declare @endPos as int set @endPos = -1 while (@position > 0 and @endPos != 0) begin set @startPos = @endPos + 1 set @endPos = charindex(@delimeter, @value, @startPos) if(@position = 1) begin if(@endPos = 0) set @endPos = len(@value) + 1 return substring(@value, @startPos, @endPos - @startPos) end set @position = @position - 1 end return null end
및 사용 :
select dbo.GetStringPartByDelimeter ('a;b;c;d;e', ';', 3)
이는 반환 :
c
-
==============================
16.이 시도:
이 시도:
CREATE function [SplitWordList] ( @list varchar(8000) ) returns @t table ( Word varchar(50) not null, Position int identity(1,1) not null ) as begin declare @pos int, @lpos int, @item varchar(100), @ignore varchar(100), @dl int, @a1 int, @a2 int, @z1 int, @z2 int, @n1 int, @n2 int, @c varchar(1), @a smallint select @a1 = ascii('a'), @a2 = ascii('A'), @z1 = ascii('z'), @z2 = ascii('Z'), @n1 = ascii('0'), @n2 = ascii('9') set @ignore = '''"' set @pos = 1 set @dl = datalength(@list) set @lpos = 1 set @item = '' while (@pos <= @dl) begin set @c = substring(@list, @pos, 1) if (@ignore not like '%' + @c + '%') begin set @a = ascii(@c) if ((@a >= @a1) and (@a <= @z1)) or ((@a >= @a2) and (@a <= @z2)) or ((@a >= @n1) and (@a <= @n2)) begin set @item = @item + @c end else if (@item > '') begin insert into @t values (@item) set @item = '' end end set @pos = @pos + 1 end if (@item > '') begin insert into @t values (@item) end return end
이런 식으로 테스트 :
select * from SplitWordList('Hello John Smith')
-
==============================
17.다음 예는 재귀 CTE를 사용
다음 예는 재귀 CTE를 사용
업데이트 2013년 9월 18일
CREATE FUNCTION dbo.SplitStrings_CTE(@List nvarchar(max), @Delimiter nvarchar(1)) RETURNS @returns TABLE (val nvarchar(max), [level] int, PRIMARY KEY CLUSTERED([level])) AS BEGIN ;WITH cte AS ( SELECT SUBSTRING(@List, 0, CHARINDEX(@Delimiter, @List + @Delimiter)) AS val, CAST(STUFF(@List + @Delimiter, 1, CHARINDEX(@Delimiter, @List + @Delimiter), '') AS nvarchar(max)) AS stval, 1 AS [level] UNION ALL SELECT SUBSTRING(stval, 0, CHARINDEX(@Delimiter, stval)), CAST(STUFF(stval, 1, CHARINDEX(@Delimiter, stval), '') AS nvarchar(max)), [level] + 1 FROM cte WHERE stval != '' ) INSERT @returns SELECT REPLACE(val, ' ','' ) AS val, [level] FROM cte WHERE val > '' RETURN END
SQLFiddle에 데모
-
==============================
18.
Alter Function dbo.fn_Split ( @Expression nvarchar(max), @Delimiter nvarchar(20) = ',', @Qualifier char(1) = Null ) RETURNS @Results TABLE (id int IDENTITY(1,1), value nvarchar(max)) AS BEGIN /* USAGE Select * From dbo.fn_Split('apple pear grape banana orange honeydew cantalope 3 2 1 4', ' ', Null) Select * From dbo.fn_Split('1,abc,"Doe, John",4', ',', '"') Select * From dbo.fn_Split('Hello 0,"&""&&&&', ',', '"') */ -- Declare Variables DECLARE @X xml, @Temp nvarchar(max), @Temp2 nvarchar(max), @Start int, @End int -- HTML Encode @Expression Select @Expression = (Select @Expression For XML Path('')) -- Find all occurences of @Delimiter within @Qualifier and replace with |||***||| While PATINDEX('%' + @Qualifier + '%', @Expression) > 0 AND Len(IsNull(@Qualifier, '')) > 0 BEGIN Select -- Starting character position of @Qualifier @Start = PATINDEX('%' + @Qualifier + '%', @Expression), -- @Expression starting at the @Start position @Temp = SubString(@Expression, @Start + 1, LEN(@Expression)-@Start+1), -- Next position of @Qualifier within @Expression @End = PATINDEX('%' + @Qualifier + '%', @Temp) - 1, -- The part of Expression found between the @Qualifiers @Temp2 = Case When @End < 0 Then @Temp Else Left(@Temp, @End) End, -- New @Expression @Expression = REPLACE(@Expression, @Qualifier + @Temp2 + Case When @End < 0 Then '' Else @Qualifier End, Replace(@Temp2, @Delimiter, '|||***|||') ) END -- Replace all occurences of @Delimiter within @Expression with '</fn_Split><fn;_Split>' -- And convert it to XML so we can select from it SET @X = Cast('<fn;_Split>' + Replace(@Expression, @Delimiter, '</fn_Split><fn;_Split>') + '</fn_Split>' as xml) -- Insert into our returnable table replacing '|||***|||' back to @Delimiter INSERT @Results SELECT "Value" = LTRIM(RTrim(Replace(C.value('.', 'nvarchar(max)'), '|||***|||', @Delimiter))) FROM @X.nodes('fn_Split') as X(C) -- Return our temp table RETURN END
-
==============================
19.나는 오래된 질문 알아요,하지만 난 어떤 사람이 내 솔루션 혜택을 누릴 수 있다고 생각합니다.
나는 오래된 질문 알아요,하지만 난 어떤 사람이 내 솔루션 혜택을 누릴 수 있다고 생각합니다.
select SUBSTRING(column_name,1,CHARINDEX(' ',column_name,1)-1) ,SUBSTRING(SUBSTRING(column_name,CHARINDEX(' ',column_name,1)+1,LEN(column_name)) ,1 ,CHARINDEX(' ',SUBSTRING(column_name,CHARINDEX(' ',column_name,1)+1,LEN(column_name)),1)-1) ,SUBSTRING(SUBSTRING(column_name,CHARINDEX(' ',column_name,1)+1,LEN(column_name)) ,CHARINDEX(' ',SUBSTRING(column_name,CHARINDEX(' ',column_name,1)+1,LEN(column_name)),1)+1 ,LEN(column_name)) from table_name
SQL 뿐인
장점 :
제한 사항 :
참고 :이 솔루션은 N.에로 하위 문자열을 제공 할 수 있습니다
한계를 극복하기 위해 우리는 다음과 같은 심판을 사용할 수 있습니다.
그러나 다시 위의 솔루션은 테이블에서 사용 할 수 없습니다 (Actaully 내가 그것을 사용할 수 없습니다).
다시 나는이 솔루션은 일부-일을 도울 수 있기를 바랍니다.
업데이트 : 기록의 경우는> 50000 성능이 저하됩니다로 루프를 사용하지 않는 것이 좋습니다
-
==============================
20.거의 모든 다른 응답 코드 분할은 폐기물 CPU 사이클을 수행하고, 불필요한 메모리 할당 문자열 인 분할을 대체하고있다.
거의 모든 다른 응답 코드 분할은 폐기물 CPU 사이클을 수행하고, 불필요한 메모리 할당 문자열 인 분할을 대체하고있다.
여기 문자열 분할을 할 수있는 더 나은 방법을 다룹니다 http://www.digitalruby.com/split-string-sql-server/
여기에 코드입니다 :
SET NOCOUNT ON -- You will want to change nvarchar(MAX) to nvarchar(50), varchar(50) or whatever matches exactly with the string column you will be searching against DECLARE @SplitStringTable TABLE (Value nvarchar(MAX) NOT NULL) DECLARE @StringToSplit nvarchar(MAX) = 'your|string|to|split|here' DECLARE @SplitEndPos int DECLARE @SplitValue nvarchar(MAX) DECLARE @SplitDelim nvarchar(1) = '|' DECLARE @SplitStartPos int = 1 SET @SplitEndPos = CHARINDEX(@SplitDelim, @StringToSplit, @SplitStartPos) WHILE @SplitEndPos > 0 BEGIN SET @SplitValue = SUBSTRING(@StringToSplit, @SplitStartPos, (@SplitEndPos - @SplitStartPos)) INSERT @SplitStringTable (Value) VALUES (@SplitValue) SET @SplitStartPos = @SplitEndPos + 1 SET @SplitEndPos = CHARINDEX(@SplitDelim, @StringToSplit, @SplitStartPos) END SET @SplitValue = SUBSTRING(@StringToSplit, @SplitStartPos, 2147483647) INSERT @SplitStringTable (Value) VALUES(@SplitValue) SET NOCOUNT OFF -- You can select or join with the values in @SplitStringTable at this point.
-
==============================
21.당신은 기능을하지 않고도 SQL에서 문자열을 분할 할 수 있습니다 :
당신은 기능을하지 않고도 SQL에서 문자열을 분할 할 수 있습니다 :
DECLARE @bla varchar(MAX) SET @bla = 'BED40DFC-F468-46DD-8017-00EF2FA3E4A4,64B59FC5-3F4D-4B0E-9A48-01F3D4F220B0,A611A108-97CA-42F3-A2E1-057165339719,E72D95EA-578F-45FC-88E5-075F66FD726C' -- http://stackoverflow.com/questions/14712864/how-to-query-values-from-xml-nodes SELECT x.XmlCol.value('.', 'varchar(36)') AS val FROM ( SELECT CAST('<e>' + REPLACE(@bla, ',', '</e><e>') + '</e>' AS xml) AS RawXml ) AS b CROSS APPLY b.RawXml.nodes('e') x(XmlCol);
당신은 임의의 문자열을 지원해야하는 경우 (XML 특수 문자 포함)
DECLARE @bla NVARCHAR(MAX) SET @bla = '<html>unsafe & safe Utf8CharsDon''tGetEncoded ÄöÜ - "Conex"<html>,Barnes & Noble,abc,def,ghi' -- http://stackoverflow.com/questions/14712864/how-to-query-values-from-xml-nodes SELECT x.XmlCol.value('.', 'nvarchar(MAX)') AS val FROM ( SELECT CAST('<e>' + REPLACE((SELECT @bla FOR XML PATH('')), ',', '</e><e>') + '</e>' AS xml) AS RawXml ) AS b CROSS APPLY b.RawXml.nodes('e') x(XmlCol);
-
==============================
22.재귀 CTE와 TVF를 사용하여 순수 세트 기반의 솔루션입니다. 당신은 가입하고 데이터 세트에이 기능을 적용 할 수 있습니다.
재귀 CTE와 TVF를 사용하여 순수 세트 기반의 솔루션입니다. 당신은 가입하고 데이터 세트에이 기능을 적용 할 수 있습니다.
create function [dbo].[SplitStringToResultSet] (@value varchar(max), @separator char(1)) returns table as return with r as ( select value, cast(null as varchar(max)) [x], -1 [no] from (select rtrim(cast(@value as varchar(max))) [value]) as j union all select right(value, len(value)-case charindex(@separator, value) when 0 then len(value) else charindex(@separator, value) end) [value] , left(r.[value], case charindex(@separator, r.value) when 0 then len(r.value) else abs(charindex(@separator, r.[value])-1) end ) [x] , [no] + 1 [no] from r where value > '') select ltrim(x) [value], [no] [index] from r where x is not null; go
용법:
select * from [dbo].[SplitStringToResultSet]('Hello John Smith', ' ') where [index] = 1;
결과:
value index ------------- John 1
-
==============================
23.SQL 서버 2016 우리의 string_split 시작
SQL 서버 2016 우리의 string_split 시작
DECLARE @string varchar(100) = 'Richard, Mike, Mark' SELECT value FROM string_split(@string, ',')
-
==============================
24.STRING_SPLIT을 사용하여 현대적인 접근 방식은 SQL 서버 2016 이상이 필요합니다.
STRING_SPLIT을 사용하여 현대적인 접근 방식은 SQL 서버 2016 이상이 필요합니다.
DECLARE @string varchar(100) = 'Hello John Smith' SELECT ROW_NUMBER() OVER (ORDER BY value) AS RowNr, value FROM string_split(@string, ' ')
결과:
RowNr value 1 Hello 2 John 3 Smith
지금은 행 번호에서 n 번째 요소를 얻을 수 있습니다.
-
==============================
25.아론 버트 랜드의 대답은 잘하지만 결함이있다. 길이 기능이 후행 공백을 제거합니다 때문에 (원래의 질문의 예이었다로) 그것은 정확하게 구분 기호로 공백을 처리하지 않습니다.
아론 버트 랜드의 대답은 잘하지만 결함이있다. 길이 기능이 후행 공백을 제거합니다 때문에 (원래의 질문의 예이었다로) 그것은 정확하게 구분 기호로 공백을 처리하지 않습니다.
다음은 공간 구분 수 있도록 작은 조정과 함께, 자신의 코드입니다 :
CREATE FUNCTION [dbo].[SplitString] ( @List NVARCHAR(MAX), @Delim VARCHAR(255) ) RETURNS TABLE AS RETURN ( SELECT [Value] FROM ( SELECT [Value] = LTRIM(RTRIM(SUBSTRING(@List, [Number], CHARINDEX(@Delim, @List + @Delim, [Number]) - [Number]))) FROM (SELECT Number = ROW_NUMBER() OVER (ORDER BY name) FROM sys.all_objects) AS x WHERE Number <= LEN(@List) AND SUBSTRING(@Delim + @List, [Number], LEN(@Delim+'x')-1) = @Delim ) AS y );
-
==============================
26.여기에 분할 문자열 및 접근 항목 X의 문제의 목표를 달성하는 기능은 다음과 같습니다
여기에 분할 문자열 및 접근 항목 X의 문제의 목표를 달성하는 기능은 다음과 같습니다
CREATE FUNCTION [dbo].[SplitString] ( @List VARCHAR(MAX), @Delimiter VARCHAR(255), @ElementNumber INT ) RETURNS VARCHAR(MAX) AS BEGIN DECLARE @inp VARCHAR(MAX) SET @inp = (SELECT REPLACE(@List,@Delimiter,'_DELMTR_') FOR XML PATH('')) DECLARE @xml XML SET @xml = '<split><el>' + REPLACE(@inp,'_DELMTR_','</el><el>') + '</el></split>' DECLARE @ret VARCHAR(MAX) SET @ret = (SELECT el = split.el.value('.','varchar(max)') FROM @xml.nodes('/split/el[string-length(.)>0][position() = sql:variable("@elementnumber")]') split(el)) RETURN @ret END
용법:
SELECT dbo.SplitString('Hello John Smith', ' ', 2)
결과:
John
-
==============================
27.구문 분석 이름과 성을위한 간단한 솔루션
구문 분석 이름과 성을위한 간단한 솔루션
DECLARE @Name varchar(10) = 'John Smith' -- Get First Name SELECT SUBSTRING(@Name, 0, (SELECT CHARINDEX(' ', @Name))) -- Get Last Name SELECT SUBSTRING(@Name, (SELECT CHARINDEX(' ', @Name)) + 1, LEN(@Name))
내 경우에는 (그리고 보이는 많은 사람들이 ...에), 나는 하나의 공백으로 구분하여 성과 이름의 목록을 가지고있다. 이것은 성과 이름을 구문 분석하는 SELECT 문 내에서 직접 사용할 수 있습니다.
-- i.e. Get First and Last Name from a table of Full Names SELECT SUBSTRING(FullName, 0, (SELECT CHARINDEX(' ', FullName))) as FirstName, SUBSTRING(FullName, (SELECT CHARINDEX(' ', FullName)) + 1, LEN(FullName)) as LastName, From FullNameTable
-
==============================
28.나는 그 말을 알아,하지만 나는 최근에 이러한 요구 사항을했고, 아래의 코드를 함께했다. 나는 사용자 정의 기능을 사용하기 위해서는 선택의 여지가 없어. 도움이 되었기를 바랍니다.
나는 그 말을 알아,하지만 나는 최근에 이러한 요구 사항을했고, 아래의 코드를 함께했다. 나는 사용자 정의 기능을 사용하기 위해서는 선택의 여지가 없어. 도움이 되었기를 바랍니다.
SELECT SUBSTRING( SUBSTRING('Hello John Smith' ,0,CHARINDEX(' ','Hello John Smith',CHARINDEX(' ','Hello John Smith')+1) ),CHARINDEX(' ','Hello John Smith'),LEN('Hello John Smith') )
-
==============================
29.글쎄, 내 모든 것을 간단 아니지만, 여기에 내가 개별 값에 쉼표로 구분 된 입력 변수를 분할하고, 테이블 변수에 넣어하는 데 사용하는 코드입니다. 나는 당신이 당신의 결과를 얻기 위해 해당 테이블 변수에 대한 기본 SELECT 쿼리를 수행 한 후 약간이를 수정할 수있는 공간을 기준으로 분할하고 확신합니다.
글쎄, 내 모든 것을 간단 아니지만, 여기에 내가 개별 값에 쉼표로 구분 된 입력 변수를 분할하고, 테이블 변수에 넣어하는 데 사용하는 코드입니다. 나는 당신이 당신의 결과를 얻기 위해 해당 테이블 변수에 대한 기본 SELECT 쿼리를 수행 한 후 약간이를 수정할 수있는 공간을 기준으로 분할하고 확신합니다.
-- Create temporary table to parse the list of accounting cycles. DECLARE @tblAccountingCycles table ( AccountingCycle varchar(10) ) DECLARE @vchAccountingCycle varchar(10) DECLARE @intPosition int SET @vchAccountingCycleIDs = LTRIM(RTRIM(@vchAccountingCycleIDs)) + ',' SET @intPosition = CHARINDEX(',', @vchAccountingCycleIDs, 1) IF REPLACE(@vchAccountingCycleIDs, ',', '') <> '' BEGIN WHILE @intPosition > 0 BEGIN SET @vchAccountingCycle = LTRIM(RTRIM(LEFT(@vchAccountingCycleIDs, @intPosition - 1))) IF @vchAccountingCycle <> '' BEGIN INSERT INTO @tblAccountingCycles (AccountingCycle) VALUES (@vchAccountingCycle) END SET @vchAccountingCycleIDs = RIGHT(@vchAccountingCycleIDs, LEN(@vchAccountingCycleIDs) - @intPosition) SET @intPosition = CHARINDEX(',', @vchAccountingCycleIDs, 1) END END
개념은 거의 동일합니다. 또 다른 대안은 SQL Server 2005의 자체 내에서 .NET 호환성을 활용하는 것입니다. 당신은 기본적으로 자신에게 문자열을 분할 한 다음 저장 프로 시저 / 함수로 그 노출 될 수 .NET에서 간단한 방법을 쓸 수 있습니다.
-
==============================
30.이것은 내가 문자열에서 토큰을 특정을 얻기 위해했던 일이다. (2008 MSSQL에서 테스트)
이것은 내가 문자열에서 토큰을 특정을 얻기 위해했던 일이다. (2008 MSSQL에서 테스트)
(에서 발견 : 우선, 다음과 같은 기능을 만들어 여기에
CREATE FUNCTION dbo.SplitStrings_Moden ( @List NVARCHAR(MAX), @Delimiter NVARCHAR(255) ) RETURNS TABLE WITH SCHEMABINDING AS RETURN WITH E1(N) AS ( SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1), E2(N) AS (SELECT 1 FROM E1 a, E1 b), E4(N) AS (SELECT 1 FROM E2 a, E2 b), E42(N) AS (SELECT 1 FROM E4 a, E2 b), cteTally(N) AS (SELECT 0 UNION ALL SELECT TOP (DATALENGTH(ISNULL(@List,1))) ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E42), cteStart(N1) AS (SELECT t.N+1 FROM cteTally t WHERE (SUBSTRING(@List,t.N,1) = @Delimiter OR t.N = 0)) SELECT Item = SUBSTRING(@List, s.N1, ISNULL(NULLIF(CHARINDEX(@Delimiter,@List,s.N1),0)-s.N1,8000)) FROM cteStart s;
과
create FUNCTION dbo.getToken ( @List NVARCHAR(MAX), @Delimiter NVARCHAR(255), @Pos int ) RETURNS varchar(max) as begin declare @returnValue varchar(max); select @returnValue = tbl.Item from ( select ROW_NUMBER() over (order by (select null)) as id, * from dbo.SplitStrings_Moden(@List, @Delimiter) ) as tbl where tbl.id = @Pos return @returnValue end
당신은 그렇게 사용할 수 있습니다 :
select dbo.getToken('1111_2222_3333_', '_', 1)
1111을 반환하는
from https://stackoverflow.com/questions/2647/how-do-i-split-a-string-so-i-can-access-item-x by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] 동적 열 수로 MySQL의 피봇 행 (0) | 2020.03.05 |
---|---|
[SQL] 열에 대해 최대 값을 갖는 행을 페치 (0) | 2020.03.05 |
[SQL] MySQL의 계층 적 재귀 쿼리 만드는 방법 (0) | 2020.03.04 |
[SQL] 는 SQL IN 절을 매개 변수화 (0) | 2020.03.04 |
[SQL] SQL 서버 동적 PIVOT 쿼리? (0) | 2020.03.04 |