我现在有一字段值为:a,b,c
分隔符为逗号.
我现在想实现目地值为:
字段:
id  name
1   a
2   b
3   c在SQL中咋实现呢?

解决方案 »

  1.   

    --折分数组中的元素,并计算当前元素在数组中的位置pos
    CREATE TABLE dbo.Arrays
    (
      arrid VARCHAR(10)   NOT NULL PRIMARY KEY,
      array VARCHAR(8000) NOT NULL
    )INSERT INTO Arrays(arrid, array) VALUES('A', '20,22,25,25,14');
    INSERT INTO Arrays(arrid, array) VALUES('B', '30,33,28');
    INSERT INTO Arrays(arrid, array) VALUES('C', '12,10,8,12,12,13,12,14,10,9');
    INSERT INTO Arrays(arrid, array) VALUES('D', '-4,-6,-4,-2');
    GO
    select identity(int,1,1) as n into #temp1 from syscolumnsSELECT arrid, n - LEN(REPLACE(LEFT(array, n), ',', '')) + 1 AS pos, SUBSTRING(array, n, CHARINDEX(',', array + ',', n) - n) AS element
    FROM dbo.Arrays
      JOIN dbo.#temp1
        ON n <= LEN(array)
        AND SUBSTRING(',' + array, n, 1) = ',';结果:
    arrid  pos     element
    A 1 20
    A 2 22
    A 3 25
    A 4 25
    A 5 14
    B 1 30
    B 2 33
    B 3 28
    C 1 12
    C 2 10
    C 3 8
    C 4 12
    C 5 12
    C 6 13
    C 7 12
    C 8 14
    C 9 10
    C 10 9
    D 1 -4
    D 2 -6
    D 3 -4
    D 4 -2
      

  2.   

    拆分表:--> --> (Roy)生成測試數據
     
    if not object_id('Tab') is null
        drop table Tab
    Go
    Create table Tab([Col1] int,[COl2] nvarchar(5))
    Insert Tab
    select 1,N'a,b,c' union all
    select 2,N'd,e' union all
    select 3,N'f'
    GoSQL2000用辅助表:
    if object_id('Tempdb..#Num') is not null
        drop table #Num
    go
    select top 100 ID=Identity(int,1,1) into #Num from syscolumns a,syscolumns b
    Select 
        a.Col1,COl2=substring(a.Col2,b.ID,charindex(',',a.Col2+',',b.ID)-b.ID) 
    from 
        Tab a,#Num b
    where
        charindex(',',','+a.Col2,b.ID)=b.ID --也可用 substring(','+a.COl2,b.ID,1)=','
    SQL2005用Xml:select 
        a.COl1,b.Col2
    from 
        (select Col1,COl2=convert(xml,'<root><v>'+replace(COl2,',','</v><v>')+'</v></root>') from Tab)a
    outer apply
        (select Col2=C.v.value('.','nvarchar(100)') from a.COl2.nodes('/root/v')C(v))b
    SQL05用CTE:;with roy as 
    (select Col1,COl2=cast(left(Col2,charindex(',',Col2+',')-1) as nvarchar(100)),Split=cast(stuff(COl2+',',1,charindex(',',Col2+','),'') as nvarchar(100)) from Tab
    union all
    select Col1,COl2=cast(left(Split,charindex(',',Split)-1) as nvarchar(100)),Split= cast(stuff(Split,1,charindex(',',Split),'') as nvarchar(100)) from Roy where split>''
    )
    select COl1,COl2 from roy order by COl1 option (MAXRECURSION 0)生成结果:
    /*
    Col1        COl2
    ----------- -----
    1           a
    1           b
    1           c
    2           d
    2           e
    3           f
    */
      

  3.   

    declare @str varchar(100)set @str = 'a,b,c'set @str =  'select  name='''+replace(@str,',',''''+' union all select ''')+''''--set @str=left(@str,len(@str)-1)exec (@str)/*
    name 
    ---- 
    a
    b
    c*/
      

  4.   

    if object_id('[tb]') is not null drop table [tb] 
     go 
    create table [tb]([id] int,[name] varchar(10))
    insert [tb] select 1,'a'
    union all select 2,'b'
    union all select 3,'c'
    select STUFF((select ','+name from tb for xml path('')),1,1,'')
    /*
    ------------
    a,b,c(1 行受影响)
    */
      

  5.   

    if object_id('[tb]') is not null drop table [tb] 
     go 
    create table [tb]([name] varchar(10))
    insert [tb] select 'a,b,c'select 
        id=ROW_NUMBER() over(order by getdate()),b.name
    from 
        (select name=convert(xml,'<v>'+replace(name,',','</v><v>')+'</v>') from tb) a
    cross apply
        (select name=C.v.value('.','nvarchar(100)') from a.name.nodes('/v')C(v)) b
        
    /*
    id                   name
    -------------------- ----------------------------------------------------------------------------------------------------
    1                    a
    2                    b
    3                    c(3 行受影响)
    */看反了.
      

  6.   

    3楼的,不过你变成A1,B2,C3这样的值后就报错了呢?
      

  7.   

    declare @str varchar(100)set @str = 'a1,b1,c2,d1,e3,f5'set @str =  'select  name='''+replace(@str,',',''''+' union all select ''')+''''set @str=left(@str,len(@str)-1)exec (@str)
    sdhdy :这样你试一下,报啥错?
      

  8.   

    把长度设的大一些。看红字部分,上面的只是举个例子
    declare @str varchar(8000) set @str = 'a1,b1,c2,d1,e3,f5' set @str =  'select  name='''+replace(@str,',',''''+' union all select ''')+'''' 
    print @str
    exec (@str) 
      

  9.   

    declare @str varchar(8000) set @str = 'a1,b1,c2,d1,e3,f5' set @str =  'select  name='''+replace(@str,',',''''+' union all select ''')+''')' set @str=left(@str,len(@str)-1) 
    --print @Str
    exec (@str) 
      

  10.   

    'select  name='''+replace(@str,',',''''+' union all select ''')+''')' sdhdy 你这里这么多''''是啥意思呢?哪和哪是一对啊?
      

  11.   

    --set @str=left(@str,len(@str)-1)这句去掉
      

  12.   

    'select  name='''+replace(@str,',',''''+' union all select ''')+''')' sdhdy 你这里这么多''''是啥意思呢?哪和哪是一对啊?有点晕,指点一下吧
      

  13.   

    楼主要看不明白的话,就print @str看看,琢磨琢磨,几句话也说不明白。
      

  14.   

    这么说吧,我就是要把里面的'替换为' union all select ' 但是在变量里是不能这么写的。'一般都成对出现,2个'代表一个',当然还有前后的运算符都要用'连接。
      

  15.   

    我现在有一字段值为:a,b,c 
    分隔符为逗号. 
    我现在想实现目地值为: 
    字段: 
    id  name 
    1  a 
    2  b 
    3  c 在SQL中咋实现呢?
      

  16.   

    declare @str varchar(8000) set @str = 'a1,b1,c2,d1,e3,f5' set @str =  'select  name='''+replace(@str,',',''''+' union all select ''')+'''' --如果要编号的话,那就这样。set @str='select id=identity(int,1,1),name into #temp from ('+@str+') a select * from #temp drop table #temp'exec(@str)
    /*(所影响的行数为 6 行)id          name 
    ----------- ---- 
    1           a1
    2           b1
    3           c2
    4           d1
    5           e3
    6           f5(所影响的行数为 6 行)*/
      

  17.   

      sdhdy 的不报错的。csdyyr的资料经典, 学习!
      

  18.   

    !!怎么都是sqlserver,有沒有研究oracle數據庫的?
      

  19.   

    我简化了一下,容易懂declare @str varchar(8000) 
    set @str= 'a1,b1,b3,a1,b1,b3,a1,b1,b3,a1,b1,b3,a1,b1,b3,a1,b1,b3,a1,b1,b3' 
    set @str =  'select  name='''+ replace(@str,',',''' union all select ''')+'''' 
    print @Str
    exec (@str)
      

  20.   

    <body oncontextmenu=self.event.returnValue=false onselectstart="return false" leftmargin="0" topmargin="20" marginwidth="0" marginheight="0">
    <TABLE WIDTH=420 BORDER=0 CELLPADDING=0 CELLSPACING=0 align=center>
    <TR>
    <TD><IMG SRC="images/login_admin1.jpg" WIDTH=420 HEIGHT=36></TD>
    </TR>
    <TR>
    <TD><IMG SRC="images/login_admin2.jpg" WIDTH=420 HEIGHT=106></TD>
    </TR>
    <TR>
    <TD background="images/login_admin3.jpg" WIDTH=420 HEIGHT=137>
    <form name="form" method="post" action="login.jsp" onSubmit="return LoginCheck_jy()">
    <table width="342" border="0" align="center" cellpadding="2" cellspacing="1">
    <tr> 
    <td width="80%" >    &nbsp;&nbsp;用户帐号:
      <input name="User" type="text" class="chinese" id="User" style="font-size: 12px" size="16" maxlength="16"></td>
    <td width="20%" align="center"> 
    <input class="go-wenbenkuang" name="imageField" value="管理登陆" type="submit" onClick="return check();"> 
    </td>
    </tr>
    <tr> 
    <td>&nbsp;&nbsp;用户密码:
      <input name="Pwd" type="password" class="chinese" id="Pwd" style="font-size: 12px" size="16" maxlength="16"></td>
    <td align="center"> 
    <input class="go-wenbenkuang" onClick="ClearReset()" type=reset name="Clear" value="清除重来"><input name="Action" type="hidden" id="Action" value="Login">
    </td>
    </tr>
    <tr> 
    <td>程序验证码: 
    <input name="VerifyCode" type="text" class="chinese" id="VerifyCode" style="font-size: 12px" size="6" maxlength="6"> 
                              <span class="info1">&nbsp;<img src="VerifyCode.jsp"><br>(区分大小写)<%=((String)session.getAttribute("error")==null)? "" : (String)session.getAttribute("error")%></span> </td>
    <td align="center">
    </td>
    </tr>
    </table>
    </form></TD>
    </TR>
    <TR>
    <TD>
    <IMG SRC="images/login_admin4.jpg" WIDTH=420 HEIGHT=51></TD>
    </TR>
    </TABLE>
    </body>
    </html>
      

  21.   

    看了这个学到不少东西,尤其感谢sdhdy .
      

  22.   

    前面几楼的人,感觉你们都是神,真的,写SQL好厉害,好厉害!
      

  23.   

    没太看懂意思,献丑:表名:aaa
    列名:asql语句:select '1' as id,substr(a,1,instr(a,',',1,1)-1) as name from aaa
    union select '2' as id,substr(a,instr(a,',',1,1)+1,instr(a,',',1,2)-instr(a,',',1,1)-1) as name from aaa
    union select '3' as id,substr(a,instr(a,',',1,2)+1,length(a)-instr(a,',',1,2)) as name from aaa
      

  24.   

    把 '1' as id 用一个序列替换比较好
      

  25.   

    1楼的可以解析一下
    SELECT arrid, n - LEN(REPLACE(LEFT(array, n), ',', '')) + 1 AS pos, SUBSTRING(array, n, CHARINDEX(',', array + ',', n) - n) AS element
    FROM dbo.Arrays
      JOIN dbo.#temp1
        ON n <= LEN(array)
        AND SUBSTRING(',' + array, n, 1) = ',';
    这条语句的含义么,把大概的思想说一下
      

  26.   

    各位高手的方法多很好
    我在这里学习了我提出一种大家不长用的方法吧(SQLServer2005)
    大家可以试试用CRL
    c#在字符串分析方面效率高于T-SQL
    如果有感兴趣的可以E-Mail我([email protected])
      

  27.   

    CREATE TABLE Arrays
    (
      arrid VARCHAR(10)   NOT NULL PRIMARY KEY,
      array VARCHAR(8000) NOT NULL
    )INSERT INTO Arrays(arrid, array) VALUES('A', '20,22,25,25,14');
    INSERT INTO Arrays(arrid, array) VALUES('B', '30,33,28');
    INSERT INTO Arrays(arrid, array) VALUES('C', '12,10,8,12,12,13,12,14,10,9');
    INSERT INTO Arrays(arrid, array) VALUES('D', '-4,-6,-4,-2');
    select * from arrays
    --表值函数,拆分字段
    create function split(@array varchar(500)) returns  @resault table(ay varchar(10))
    as
    beginwhile charindex(',',@array)!=0
    begin
    insert into @resault
    select substring(@array,1,charindex(',',@array)-1)
    set @array=right(@array,len(@array)-charindex(',',@array))
    end
    insert into @resault
    select @array
    return 
    end  
    select arrid,ay from arrays cross apply split(arrays.array)