2016-05-15 2 views
1

Je cherchais une solution dans StackOverflow mais je n'ai rien trouvé d'utile. Je suis confronté à un problème et j'espère que quelqu'un voudra m'aider.Division de plusieurs valeurs délimitées en plusieurs lignes

Je valeur comme ceci:

Create table DemoRecords 
(
    CustID int identity (1,1), 
    CustomerName varchar(50), 
    CurrencyCode varchar(50), 
    CurrentBalance varchar(50), 
    DateValue varchar(50) 
) 
GO 

INSERT INTO DemoRecords VALUES ('Mr. X', 'BDTýUSDýGBP','10500ý2500ý1050','20150101ý20150201ý20150301') 

..et je besoin d'une sortie comme ceci: (S'il vous plaît jeter un oeil à l'image ci-joint)

enter image description here Picture

S'il vous plaît don ne me suggère pas d'utiliser CTE car il y a plus de 100 colonnes dans ce tableau.

+0

Vous pouvez écrire une simple boucle pour extraire les bits qui vous intéressent et les placer dans votre base de données. –

+0

Remarque: Même après avoir divisé les valeurs, vous devrez toujours translater la DateValue à un type de données de date réel. –

+0

Pourriez-vous s'il vous plaît expliquer un peu plus parce que je suis totalement confus :( –

Répondre

2

Voici une fonction pour diviser une chaîne en rangées. Vous trouverez ci-dessous une requête sur votre table demorecords qui utilise la fonction pour obtenir le résultat demandé.

create function dbo.split 
(
    @delimited nvarchar(max), 
    @delimiter nvarchar(5) 
) 
returns @rows table 
(
    rownumber int not null identity(1,1), 
    value nvarchar(max) not null 
) 
as 
begin 
    if @delimited is null return 

    declare @delr_len int = len(@delimiter) 
    declare @start_at int = 1 
    declare @end_at int 
    declare @deld_len int 

    while 1=1 
    begin 
     set @end_at = charindex(@delimiter,@delimited,@start_at) 
     set @deld_len = case @end_at when 0 then len(@delimited) else @[email protected]_at end 
     insert into @rows (value) values(substring(@delimited,@start_at,@deld_len)); 
     if @end_at = 0 break; 
     set @start_at = @end_at + @delr_len 
    end 

    return 
end 
go 


select custid, customername, currencycode=currencycode.value, currentbalance=currentbalance.value, datevalue=datevalue.value 
    from demorecords r 
    cross apply (select rownumber, value from dbo.split(r.currencycode,'ý')) currencycode 
    cross apply (select rownumber, value from dbo.split(r.currentbalance,'ý') where rownumber = currencycode.rownumber) currentbalance 
    cross apply (select rownumber, value from dbo.split(r.datevalue,'ý') where rownumber = currencycode.rownumber) datevalue 

Si vous avez une colonne qui peut contenir les valeurs manquantes, utiliser une partie extérieure au lieu d'appliquer une demande d'adhésion intérieure du résultat de la fonction de cette colonne. Dans l'exemple suivant, la colonne est DateValue valeur manquante 3 et la valeur 4.

INSERT INTO DemoRecords VALUES ('Mr. X', 'BDTýUSDýGBPýEUR','10500ý2500ý1050ý','ý') 

select custid, customername, currencycode=currencycode.value, currentbalance=currentbalance.value, datevalue=datevalue.value 
from demorecords r 
cross apply (select rownumber, value from dbo.split(r.currencycode,'ý')) currencycode 
cross apply (select rownumber, value from dbo.split(r.currentbalance,'ý') where rownumber = currencycode.rownumber) currentbalance 
outer apply (select rownumber, value from dbo.split(r.datevalue,'ý') where rownumber = currencycode.rownumber) datevalue 

Sinon, vous pouvez nettoyer votre entrée à ne pas manquer les valeurs. Dans l'exemple ci-dessus, je m'attendrais à ce que DateValue soit 'ýýý' et non 'ý'. Si votre situation le permet, vous préférerez peut-être trouver et réparer ceux-ci sans utiliser de jointure externe.

+0

Merci beaucoup Matt Dolfin :) –

+0

Cher Matt, j'ai un scénario. Pourriez-vous s'il vous plaît exécuter votre fonction sur ce ci-dessous des données et voir ce qui se passe. INSCRIRE DANS LES VALEURS de DemoRecords ('Mr. X', 'BDTýUSDýGBPYEUR', '10500ý2500ý1050ý', 'ý'). le rownumber ne correspond pas aux autres colonnes, ce qui n'obtient pas la sortie attendue. –

+0

@Sajid Wasim, dans votre dernier scénario, DateValue manque les troisième et quatrième valeurs. Je m'attendrais à ce qu'il ait la valeur 'ýýý', pas 'ý'. Vous pouvez simplement utiliser une application externe au lieu d'une application interne pour joindre le résultat de la fonction pour cette colonne. Voir ma réponse mise à jour. Ou, vous pouvez nettoyer votre entrée pour avoir le bon nombre de colonnes. –