SQL替换字符串中特定字符的序列号

时间:2015-08-12 14:01:36

标签: sql sql-server tsql sql-server-2008-r2

输入表包含如下字符串:

Col_Name
---------------
YXNYNXYYZY
YYZZY
-- and 100's of rows

我想找到特定的字符Y,并创建输出字段,如下所示:

Col_Name
----------------
1,4,7,8,10
1,2,5

我正在尝试使用sql函数找到解决方案,如replace,len,charindex等,但无法到达输出。请帮忙。

4 个答案:

答案 0 :(得分:0)

此解决方案有效,但您应该考虑更改模型,因为这种方法可能很慢,不应该是SQL Server的工作。

declare @search char(1) = 'Y'

; with input(string) as (
    Select * From (values('YXNYNXYYZY'), ('YYZZY')) as input(string)
), find(id, string, pos) as ( => get 1 row each Y found and its position
    select 0, string, CHARINDEX(@search, string, 0) From input
    Where CHARINDEX(@search, string, 0) > 0
    Union All
    select id+1, string, CHARINDEX(@search, string, pos+1) From find
    Where CHARINDEX(@search, string, pos+1) > 0
)
--Select * from find => 1 position per row
Select STUFF( --=> concatenate all position by string
    (
        Select ', ' + CAST([pos] AS Varchar(10)) 
        From find f
        Where (string = r.string) 
        Order By string, id
        For XML PATH(''),TYPE
    ).value('(./text())[1]','Varchar(100)')
  ,1,2,'') AS x
From find r
Group BY string

答案 1 :(得分:0)

在函数的帮助下,我们可以带来这些值

alter FUNCTION [dbo].[GetPosition] 
(
@txt varchar(max),
@Pat varchar(max)
)
RETURNS 
@tab TABLE 
(
 ID int
)
AS
BEGIN
Declare @pos int
Declare @oldpos int
Select @oldpos=0
select @pos=patindex(@pat,@txt) 
while @pos > 0 and @oldpos<>@pos
 begin
   insert into @tab Values (@pos)
   Select @oldpos=@pos
   select @pos=patindex(@pat,Substring(@txt,@pos + 1,len(@txt))) + @pos

end

RETURN 
END

GO

通话功能

SELECT 
stuff(
(
    SELECT ','+ cast(ID as nvarchar(4)) FROM dbo.[GetPosition] ('YXNYNXYYZY','%Y%')  FOR XML PATH('')
),1,1,'') 

答案 2 :(得分:0)

这对于像php或python这样的脚本语言来说是微不足道的。将整个数据集转储到数组并检查每个值。事件100的行不会成为问题。

  1. Load the CsV File
  2. 在数组中搜索值。
  3. //伪代码(未经测试)

    $Data = str_getcsv('c:\data\dumpeddata.csv');
    
    foreach ($Data as $LineNo => $LineDetails) {
      foreach($LineDetails as $ColNo => $ColData){
       if (strpos($ColData , 'Y') !== false){
         $Found .= "\nLine:$LineNo,Col:$ColNo";
        }
     }
    }
    echo $Found;
    

    你会惊讶地发现它的速度有多快。

答案 3 :(得分:0)

declare @n int = (select charindex('Y',col_name,1) from tablename)
declare @l int = (select len(col_name) from tablename)
declare @res varchar(100) = ''
while @n <= @l and (select charindex('Y',col_name,@n) from tablename) <> 0
begin
set @res = @res + cast(select charindex('Y',col_name,@n) from tablename as varchar) + ' '
set @n = (select charindex('Y',col_name,@n) from tablename) + 1
end
select @res

这给了你一个想法。如果必须重复这样做,最好将其包装在一个函数中。