【问题标题】:SQL replace with serial number for the specific occurrence of a character in a stringSQL 用序列号替换字符串中特定出现的字符
【发布时间】:2023-03-27 07:43:01
【问题描述】:

输入表有这样的字符串:

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

我想找到字符 Y 的具体出现,并创建如下输出字段:

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

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

【问题讨论】:

  • 您的问题似乎丢失了。您在尝试完成此操作时遇到了什么问题?
  • 您尝试了什么,为什么没有成功?包括任何错误消息。
  • 在 SQL 中,您通常希望每一列(每一行)包含 一个 值(无论是字符串、int 等)。 SQL Server 有两种设计用于保存多个值的数据类型 - 表本身(以行的形式,用于重复相同“类型”值的实例)和 XML。您是否要求输出格式一成不变?
  • 对不起,我不是 SQL 专家。我现在编辑了这个问题。

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


【解决方案1】:

此解决方案有效,但您应该考虑更改您的模型,因为这种方法可能很慢并且不应该是 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

【讨论】:

    【解决方案2】:

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

    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,'') 
    

    【讨论】:

      【解决方案3】:

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

      1. Load the CsV File
      2. 在数组中搜索值。

      //伪代码(未测试)

      $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;
      

      你会惊讶于它的运行速度。

      【讨论】:

        【解决方案4】:
        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
        

        这给了你一个想法。如果必须重复执行此操作,最好将其包装在一个函数中。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2020-03-14
          • 1970-01-01
          • 1970-01-01
          • 2012-08-09
          • 1970-01-01
          相关资源
          最近更新 更多