2013-05-09 46 views
0

我有以下查询为我工作到现在。通过多个分隔符将varchar列拆分为标记(词)并将它们作为记录

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 

的结果。

+0

你可以张贴一些样品之前运行此数据和要求的输出 – praveen 2013-05-09 06:44:57

+0

@parveen增加了一些我如何使用它的例子。 – Ankit 2013-05-09 06:51:08

回答

1

如果您有一个查询适用于空格,则很容易修改其他字符空格,例如,

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 
+0

@非常感谢您的先生,但我认为在tmp CTE的Anchor查询中应该是“从Prod2”而不是“从产品”。 – Ankit 2013-05-09 07:25:53

+0

绝对正确的Ankit。那么发现 - 这解决了你的问题吗? – RichardTheKiwi 2013-05-09 09:15:54

0

调用while循环动态和这里dee_split传为@var列的值的代码是一个用户自定义函数,运行此查询执行的功能dee_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