2012-10-31 24 views
6

Olası Çoğalt:
Turning a Comma Separated string into individual rowsBölünmüş değerler

Bir saklı yordam aşağıdaki çıkışı ve birden çok satırda değerlerini bölmek için en iyi yolu merak ediyorum.

reference name       subjects  subjectstitle 
LL9X81MT Making and Decorating Pottery F06,F27,F38  NULL 

Ben virgül evinde denekler alanını Döşeme ve veri aşağıdaki gibi olacaktır böylece üç sıra üzerinden bilgi kopyalamanız gerekmez.

reference name       subjects  subjectstitle 
LL9X81MT Making and Decorating Pottery F06  NULL 
LL9X81MT Making and Decorating Pottery F27  NULL 
LL9X81MT Making and Decorating Pottery F38  NULL 

Bu SP'leri kurmak için MS SQL Server 2008 kullanıyorum ve konuların nasıl ayrılacağı konusunda biraz yardıma ihtiyacım var.

sayesinde

+0

Veriler bu biçime nasıl girer? İlk etapta düzgün bir şekilde geri getiremez misin? – podiluska

cevap

14

Buna benzer tablo değerli bölünmüş işlevinin çeşit kullanmak isteyecektir: yourtable ile katılmak

create FUNCTION [dbo].[Split](@String varchar(MAX), @Delimiter char(1))  
returns @temptable TABLE (items varchar(MAX))  
as  
begin  
    declare @idx int  
    declare @slice varchar(8000)  

    select @idx = 1  
     if len(@String)<1 or @String is null return  

    while @idx!= 0  
    begin  
     set @idx = charindex(@Delimiter,@String)  
     if @idx!=0  
      set @slice = left(@String,@idx - 1)  
     else  
      set @slice = @String  

     if(len(@slice)>0) 
      insert into @temptable(Items) values(@slice)  

     set @String = right(@String,len(@String) - @idx)  
     if len(@String) = 0 break  
    end 
return 
end; 

Daha sonra outer apply kullanabilirsiniz:

select t1.reference, 
    t1.name, 
    t1.subjectstitle, 
    i.items subjects 
from yourtable t1 
outer apply dbo.split(t1.subjects, ',') i 

Böyle bir sonucun verilmesi:

| REFERENCE |       NAME | SUBJECTSTITLE | SUBJECTS | 
------------------------------------------------------------------------ 
| LL9X81MT | Making and Decorating Pottery |  (null) |  F06 | 
| LL9X81MT | Making and Decorating Pottery |  (null) |  F27 | 
| LL9X81MT | Making and Decorating Pottery |  (null) |  F38 | 
Eğer bölünmüş fonksiyonu olmadan bunu istiyorsanız

sonra CTE kullanabilirsiniz SQL fiddle with Demo

bakınız:

;with cte (reference, name, subjectstitle, subjectitem, subjects) as 
(
    select reference, 
    name, 
    subjectstitle, 
    cast(left(subjects, charindex(',',subjects+',')-1) as varchar(50)) subjectitem, 
     stuff(subjects, 1, charindex(',',subjects+','), '') subjects 
    from yourtable 
    union all 
    select reference, 
    name, 
    subjectstitle, 
    cast(left(subjects, charindex(',',subjects+',')-1) as varchar(50)) , 
    stuff(subjects, 1, charindex(',',subjects+','), '') subjects 
    from cte 
    where subjects > '' 
) 
select reference, name, subjectstitle, subjectitem 
from cte 

SQL Fiddle with Demo

+0

+1: Siz * DIŞI UYGULAMALARI ile daha iyi bir yer olabilirsiniz, sadece durumda ... – MatBailie

+0

@Dems muhtemelen doğru, düzeltme için teşekkürler. – Taryn

+0

Bu borad üzerinde, bu konuyla ilgili bir konu zaten var ve orada çözülüyor gibi görünüyor. http://stackoverflow.com/questions/5493510/turning-a-comma-separated-string-into-individualrows – Jester

9

Bu bölünmüş fonksiyonu olmadan yapacak Bkz

SELECT T1.reference, T1.name, T2.my_Splits AS subjects, T1.subtitile 
FROM 
(
    SELECT *, 
    CAST('<X>'+replace(T.subjects,',','</X><X>')+'</X>' as XML) as my_Xml 
    FROM [yourTable] T 
) T1 
CROSS APPLY 
( 
SELECT my_Data.D.value('.','varchar(50)') as my_Splits 
FROM T1.my_Xml.nodes('X') as my_Data(D) 
) T2 
+2

Çok hoş. Harika çalışıyor. – smoore4

+0

Bu harika. Ayrık değerler ile birlikte ilerlemek için bir sıra numarası eklemenin bir yolu var mı? – aaaantoine

+0

Bence bunu anladım. T2'deki "my_splits" in hemen üstündeki ek bir sütun ekleyin: "row_number()" (my_data.D ile sırala) sequence_num olarak, '' ' – aaaantoine