VARCHAR(255)
0 또는 1 만 포함 된 문자열 ( )이 있습니다.
모든 위치를 검색하고 쉼표로 구분 된 문자열로 반환해야합니다. https://dba.stackexchange.com/questions/41961/how-to-find-all-positions-of-a-string-within-another-string의 솔루션을 사용하여 두 개의 쿼리를 작성했습니다.
지금까지 내 코드는 다음과 같습니다.
DECLARE @TERM VARCHAR(5);
SET @TERM = '1';
DECLARE @STRING VARCHAR(255);
SET @STRING = '101011011000000000000000000000000000000000000000';
DECLARE @RESULT VARCHAR(100);
SET @RESULT = '';
SELECT
@RESULT = @RESULT + CAST(X.pos AS VARCHAR(10)) + ','
FROM
( SELECT
pos = Number - LEN(@TERM)
FROM
( SELECT
Number
,Item = LTRIM(RTRIM(SUBSTRING(@STRING, Number, CHARINDEX(@TERM, @STRING + @TERM, Number) - Number)))
FROM
( SELECT ROW_NUMBER () OVER (ORDER BY [object_id]) FROM sys.all_objects
) AS n ( Number )
WHERE
Number > 1
AND Number <= CONVERT(INT, LEN(@STRING))
AND SUBSTRING(@TERM + @STRING, Number, LEN(@TERM)) = @TERM
) AS y
) X;
SELECT
SUBSTRING(@RESULT, 0, LEN(@RESULT));
DECLARE @POS INT;
DECLARE @OLD_POS INT;
DECLARE @POSITIONS VARCHAR(100);
SELECT
@POSITIONS = '';
SELECT
@OLD_POS = 0;
SELECT
@POS = PATINDEX('%1%', @STRING);
WHILE @POS > 0
AND @OLD_POS <> @POS
BEGIN
SELECT
@POSITIONS = @POSITIONS + CAST(@POS AS VARCHAR(2)) + ',';
SELECT
@OLD_POS = @POS;
SELECT
@POS = PATINDEX('%1%', SUBSTRING(@STRING, @POS + 1, LEN(@STRING))) + @POS;
END;
SELECT
LEFT(@POSITIONS, LEN(@POSITIONS) - 1);
이것이 더 빠르고 더 잘 할 수 있는지 궁금합니다. 단일 문자 위치 만 검색하고 있으며 문자열 (0 및 1)에 나타날 수있는 문자가 두 개뿐입니다.
이 코드를 사용하여 두 개의 함수를 빌드하고 1000 개의 레코드에 대해 실행하고 동일한 결과를 얻었으므로 어느 것이 더 좋은지 알 수 없습니다.
단일 레코드의 경우 두 번째 부분은 CPU를 제공하고 프로파일 러에서 읽기는 0과 같습니다. 여기서 첫 번째 코드는 CPU = 16이고 읽기 = 17입니다.
다음과 같은 결과를 얻을 필요가 있습니다. 1,3,5,6,8,9
(여러 번 발생하는 경우), 3
단일 발생에 NONE
대해 하나도없는 경우.
일부 tally
표 및 xml
솔루션 :
DECLARE @STRING NVARCHAR(100) = '101011011000000000000000000000000000000000000000';
;with cte as(select ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) p
from (values(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) t1(n) cross join
(values(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) t2(n) cross join
(values(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) t3(n))
SELECT STUFF((SELECT ',' + CAST(p AS VARCHAR(100))
FROM cte
WHERE p <= LEN(@STRING) AND SUBSTRING(@STRING, p, 1) = '1'
FOR XML PATH('')), 1, 1, '')
1에서 1000까지의 숫자를 생성하고 (문자열 길이가 더 크면 더 많은 조인을 추가) substring
함수 필터에 필요한 값을 생성합니다. 그런 다음 행을 쉼표로 구분 된 값으로 연결하는 표준 트릭입니다.
이전 버전의 경우 :
;with cte as(SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) p
FROM sys.all_columns a CROSS JOIN sys.all_columns b)
SELECT STUFF((SELECT ',' + CAST(p AS VARCHAR(100))
FROM cte
WHERE p <= LEN(@STRING) AND SUBSTRING(@STRING, p, 1) = '1'
FOR XML PATH('')), 1, 1, '')
다음은 범위 생성에 대한 좋은 기사입니다. http://dwaincsql.com/2014/03/27/tally-tables-in-t-sql/
편집하다:
;with cte as(SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) p
FROM (SELECT 1 AS rn UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 ) t1 CROSS JOIN
(SELECT 1 AS rn UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 ) t2 CROSS JOIN
(SELECT 1 AS rn UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 ) t3 CROSS JOIN
(SELECT 1 AS rn UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 ) t4 CROSS JOIN
(SELECT 1 AS rn UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 ) t5 CROSS JOIN
(SELECT 1 AS rn UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 ) t6)
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다