【发布时间】:2016-02-02 08:30:20
【问题描述】:
我的字符串 (VARCHAR(255)) 只包含零或一。
我需要搜索所有位置并将它们作为逗号分隔的字符串返回。
我使用来自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 条记录并在同一时间得到相同的结果,所以我不知道哪个更好。
对于单条记录,第二部分在 Profiler 中给出 CPU 和读取等于 0,其中第一段代码给我 CPU=16 和读取=17。
我需要得到如下所示的结果:1,3,5,6,8,9(多次出现时),3 表示单次出现,NONE 如果没有出现。
【问题讨论】:
-
这必须在SQL中完成吗?识别所有
1的职位的目的是什么? -
理想情况下,更改所需的输出,以及可能的存储设计。如果您需要处理多个值,则填充到字符串中的逗号分隔值应该是 last 的手段。 SQL Server 具有设计 用于保存多个值的类型,例如 tables 和 XML。
-
@DStanley 我有一个包含选项的表。有 100 列。这是一个非常古老的数据库。行只能有单个值,例如行有单个
1,但旧行有错误。我正在创建搜索这些行并列出它们的报告。我已经将值转换为 01 字符串,现在我需要知道这些值的位置才能获得选项编号。 -
@Damien_The_Unbeliever 我无法更改输出,这是我得到的要求之一。我必须以我的问题中描述的格式显示具有无效值的行(每行超过一个 1)
-
@Misiu 如果有可能在应用层这样做,那会容易得多。 SQL 不是为那些类型的非基于集合的操作而设计的。
标签: sql sql-server tsql sql-server-2005