Sql 通过多个分隔符将varchar列拆分为标记(字),并将它们作为记录获取

Sql 通过多个分隔符将varchar列拆分为标记(字),并将它们作为记录获取,sql,sql-server,sql-server-2008,Sql,Sql Server,Sql Server 2008,到目前为止,我有以下问题需要解决 with tmp(product_id , Token, product_name) as ( select product_id, cast ( LEFT(product_name, CHARINDEX(' ',product_name+' ')-1) as varchar(100)), STUFF(product_name, 1, CHARINDEX(' ',product_name+' '), '') from P

到目前为止,我有以下问题需要解决

    with tmp(product_id , Token, product_name) as (
    select product_id,  cast ( LEFT(product_name, CHARINDEX(' ',product_name+' ')-1) as varchar(100)),
        STUFF(product_name, 1, CHARINDEX(' ',product_name+' '), '')
    from Products 
    union all
    select product_id, cast (LEFT(product_name, CHARINDEX(' ',product_name+' ')-1) as varchar(100)),
        STUFF(product_name, 1, CHARINDEX(' ',product_name+' '), '')
    from tmp
    where product_name > ''
    )

    select product_id, Token from tmp
这将按空格分割产品名称并作为记录提供给我

但现在我不仅需要按空格分割产品名称,还需要按空格、连字符和逗号分割产品名称。我不知道怎样才能做到这一点

任何形式的帮助都是值得感激的

编辑-示例

如果产品表包含以下内容

product_id, product_name
1, JVC-600.BLACK
2, M cb-588
那我需要

product_id, token
1, JVC
1, 600
1, BLACK
2, M
2, cb
2, 588

因此。

如果您有一个适用于空格的查询,一个非常简单的修改就是将其他字符也变成空格,例如

with Prod2 as (
  select *, product_name2 = replace(replace(product_name,'.',' '),'-',' ')
  from products
)
,tmp(product_id , Token, product_name) as (
select product_id,  cast ( LEFT(product_name2, CHARINDEX(' ',product_name2+' ')-1) as varchar(100)),
    STUFF(product_name2, 1, CHARINDEX(' ',product_name2+' '), '')
from Prod2 
union all
select product_id, cast (LEFT(product_name, CHARINDEX(' ',product_name+' ')-1) as varchar(100)),
    STUFF(product_name, 1, CHARINDEX(' ',product_name+' '), '')
from tmp
where product_name > ''
)

select product_id, Token from tmp

通过使用while循环动态传递@var列的值来调整代码,这里dee_split是一个用户定义的函数,在运行此查询之前,执行函数dee_split,您需要做的是使用replace函数将所有特殊字符转换为单个字符,然后将其传递给split函数

        DROP TABLE #temp;
        Create table #temp
        (
        product_id varchar(10),
        product_name varchar(100)
        )

        Insert into #temp
        values  
        ('1','JVC-600.BLACK'),
        ('2','M cb-588') 

     Select * from #temp

      DECLARE @var VARCHAR(100)
SET @var='JVC-600.BLACK'

Select   @var=Replace(Replace(Replace (@var,'-','|'),'.','|'),' ','|')

    Select * from dee_split (@var,'|',null)   
函数dee_split在运行上述查询之前运行此函数

     CREATE FUNCTION dee_split 
    ( 
     @str varchar(max),
     @spliter char(1),
     @colspliter char(1) = null
    )
    RETURNS @tname TABLE(item VARCHAR(1000),item1 VARCHAR(1000))
    AS
    BEGIN
     DECLARE @string XML
     IF LEN(@str)=0
     BEGIN
      INSERT INTO @tname VALUES(null,null)
      RETURN
     END
     if @colspliter is null
     begin
     IF CHARINDEX(@spliter,@str,0) <> 0
     BEGIN
      SELECT @string= CONVERT(XML,'<root1><node>'+REPLACE(@str,@spliter,'</node><node>')+'</node></root1>')

      INSERT INTO @tname(item)
      SELECT  [Value]=T.c.value('.','varchar(20)')
       FROM @string.nodes('/root1/node') T(c)
     END
     end
     ELSE
     BEGIN 
      IF @str IS NOT NULL
      BEGIN 
       IF  @colspliter IS NOT NULL
       SELECT @string= CONVERT(XML,'<root1><r1><node>'+REPLACE(REPLACE(@str,@colspliter,'</node><node1>'),@spliter,'</node1></r1><r1><node>')+'</node1></r1></root1>')
       INSERT INTO @tname 
       SELECT col.value('data(node[1])','varchar(16)') item,
       col.value('data(node1[1])','varchar(9)') item1
       FROM @string.nodes('root1/r1') AS tbl(col)
      END
     END
    RETURN
    END
创建函数dee\u split
( 
@str varchar(最大值),
@拆分器字符(1),
@colspliter字符(1)=null
)
返回@tname表(item VARCHAR(1000),item 1 VARCHAR(1000))
作为
开始
声明@stringxml
如果LEN(@str)=0
开始
插入@tname值(null,null)
返回
结束
如果@colspliter为null
开始
如果CHARINDEX(@spliter,@str,0)0
开始
选择@string=CONVERT(XML、+REPLACE(@str、@spliter、)+“”)
插入@tname(项目)
选择[Value]=T.c.Value('.','varchar(20)')
来自@string.nodes('/root1/node')T(c)
结束
结束
其他的
开始
如果@str不为空
开始
如果@colspliter不为NULL
选择@string=CONVERT(XML),+REPLACE(REPLACE(@str,@colspliter,),@spliter,)+“”)
插入@tname
选择列值('data(node[1]),'varchar(16')项,
列值('data(node1[1]),'varchar(9')项1
从@string.nodes('root1/r1')开始作为tbl(col)
结束
结束
返回
结束

您可以发布一些示例数据和所需的output@parveen添加了一些我需要它如何工作的示例。@非常感谢,先生,但我认为在tmp CTE的锚查询中,它应该是“来自Prod2”,而不是“来自产品”。绝对正确。很好的发现-这能解决你的问题吗?