Solved

Parse single field into multiple columns

Posted on 2006-10-24
8
659 Views
Last Modified: 2008-02-01
Greetings Experts,

Using SQL Server 2005, I need to parse a single field into 10 columns separated by the '-'. Please review the attached sample data below:

1-01-003-2843-000100-9495445-0003-0009-2434-082906
1-01-004-3518-001472-5650553-0007-0011-2434-071906
1-01-004-3518-001840-5650395-0016-0023-2434-071806
1-01-004-3518-006300-5650625-0070-0180-0696-090906
1-01-025-3520-001200-0263780-0013-0019-2434-072106
1-01-036-2318-006720-9453664-0214-0509-2434-082206
1-01-036-2318-010080-9492002-0433-0764-2434-070406


Your help is greatly appreciated,

0
Comment
Question by:malc77
8 Comments
 
LVL 10

Expert Comment

by:AaronAbend
Comment Utility
create this function to pivot your rows... may take some tweaking.. you did not provide much for table structures...

create procedure pivoter   as
declare getrows cursor for
SELECT myfield
FROM mytable
WHERE .... - your constraints

declare @onecode varchar(20)
declare @alllcodes varchar(2000)
declare @dash varchar(1)
begin
set @dash='' --starts empty
open getrows;
fetch next from getrows into @onecode;
while (@@fetch_status=0)
begin
   set @allcodes = @allcodes + @dash+ @onecode    
   set @dash= '-'
   fetch next from getrows into @onecode;

end
close getrows;
deallocate getrows;

end
0
 
LVL 9

Expert Comment

by:dduser
Comment Utility
Create Procedure TempProc as

Declare @TempVal as Varchar(255)
Declare @InsertVal as Varchar(20)
Declare @SelectVal as Varchar(200)

Declare GetData Cursor For
Select myField from myTable

Fetch Next from GetData into @SelectVal

While (@@Fetch_Status = 0)
Begin

                      Set @TempVal = @SelectVal
                      While (PatIndex('%-%',@TempVal) <> 0)
                      Begin
                                        Set @InsertVal = Left(@TempVal,PatIndex('%-%',@TempVal) - 1)
                                        Set @TempVal = Right(@TempVal,Len(@TempVal) - PatIndex('%-%',@tempVal))
                                        Insert into TempTable (@InsertVal)
                      End
                      Insert into TempTable (@InsertVal)
End

Return




0
 
LVL 7

Accepted Solution

by:
LandyJ earned 500 total points
Comment Utility
If you want to place the data into individual columns, just a bit more manipulation will be needed.  This solution will work as long as the data has the same format for all rows and there will always be 10 columns of data output.

hth,
Landy

Here's the whole test script:

drop table #Data
drop table #Step
drop table #Pivot

CREATE TABLE #Data (
      Col01 varchar(100)
)

CREATE TABLE #Step (
      rowID int,
      colID int identity,
      val varchar(100)
)

CREATE TABLE #Pivot (
      rowID int,
      Col01 varchar(100),
      Col02 varchar(100),
      Col03 varchar(100),
      Col04 varchar(100),
      Col05 varchar(100),
      Col06 varchar(100),
      Col07 varchar(100),
      Col08 varchar(100),
      Col09 varchar(100),
      Col10 varchar(100)
)

-- Replace these with the INSERT INTO #Data SELECT FieldName from MyTable WHERE xFld = Cond1 ....
insert into #Data VALUES ('1-01-003-2843-000100-9495445-0003-0009-2434-082906')
insert into #Data VALUES ('1-01-004-3518-001472-5650553-0007-0011-2434-071906')
insert into #Data VALUES ('1-01-004-3518-001840-5650395-0016-0023-2434-071806')
insert into #Data VALUES ('1-01-004-3518-006300-5650625-0070-0180-0696-090906')
insert into #Data VALUES ('1-01-025-3520-001200-0263780-0013-0019-2434-072106')
insert into #Data VALUES ('1-01-036-2318-006720-9453664-0214-0509-2434-082206')
insert into #Data VALUES ('1-01-036-2318-010080-9492002-0433-0764-2434-070406')

declare cur_Pivot cursor for
      Select * from #Data
declare @row int, @col int,
      @Data varchar(100)
      
select @row= 0, @col = 0, @Data = ''

open cur_Pivot
FETCH NEXT from cur_Pivot INTO @Data

WHILE @@Fetch_Status = 0
  Begin
      INSERT INTO #Step
            (rowID, val)
      SELECT @row, *
      FROM udf_strSplit(@Data, '-')

      select @row = @row + 1
      FETCH NEXT from cur_Pivot INTO @Data
  End
 
close cur_Pivot
deallocate cur_Pivot

insert into #Pivot
SELECT rowID,
    MAX(CASE colID % 10 WHEN 1 THEN val ELSE '' END) AS Col01,
    MAX(CASE colID % 10 WHEN 2 THEN val ELSE '' END) AS Col02,
    MAX(CASE colID % 10 WHEN 3 THEN val ELSE '' END) AS Col03,
    MAX(CASE colID % 10 WHEN 4 THEN val ELSE '' END) AS Col04,
    MAX(CASE colID % 10 WHEN 5 THEN val ELSE '' END) AS Col05,
    MAX(CASE colID % 10 WHEN 6 THEN val ELSE '' END) AS Col06,
    MAX(CASE colID % 10 WHEN 7 THEN val ELSE '' END) AS Col07,
    MAX(CASE colID % 10 WHEN 8 THEN val ELSE '' END) AS Col08,
    MAX(CASE colID % 10 WHEN 9 THEN val ELSE '' END) AS Col09,
    MAX(CASE colID % 10 WHEN 0 THEN val ELSE '' END) AS Col10
from #Step
group by rowID

select * from #Pivot


AND, you'll need this udf:

CREATE FUNCTION  dbo.udf_strSplit (
                  @string varchar(8000),
                  @splitter char( 1)
                  )
RETURNS @res TABLE (val varchar( 8000))
AS
Begin
      IF SUBSTRING (@string, len ( @string), 1) <> @splitter
            SET @string= @string+@splitter

      Declare @start bigint,
            @word varchar( 8000),
            @charindex bigint,
            @i bigint
      SELECT @i=1, @start=1, @charindex= charindex( @splitter, @string, @start)

      WHILE (@charindex <> 0)
        Begin
            SET @word= substring( @string, @start, @charindex - @start)
            SET @start= @charindex +1
            SET @charindex= charindex( @splitter, @string, @start)
            INSERT INTO @res  VALUES (@word)
            SET @i=@i+1
      End

      RETURN
end

0
 

Author Comment

by:malc77
Comment Utility
Greetings,

Thanks for responding and forgive for not adding the table structure, (still a bit of a novice).  

My Table structure is as follows

AuxAcctAsmnt_1      nvarchar
Cost Ctr                      nvarchar
Cost Elem#      nvarchar
Cost element name      nvarchar
Nme                      nvarchar                                                   !!!!!!!! (parsed into the fields below)!!!!!!!!!     Nme = '1-01-003-2843-000100-9495445-0003-0009-2434-082906'
[Name of offsetting account]      nvarchar
RefDocNo                      nvarchar
Per                      nvarchar
User                      nvarchar
Value ObjCurr      float
Doc# Date                      datetime
Posting Date      datetime
Mde                      varchar                  Insert from parsed Nme field
SrvTyp                      varchar                  Insert from parsed Nme field
Supplier                      varchar                  Insert from parsed Nme field
Origin                      varchar                  Insert from parsed Nme field
Quantity                      varchar                  Insert from parsed Nme field
Material                      varchar                  Insert from parsed Nme field
ActlWght                      varchar                  Insert from parsed Nme field
DimWght                      varchar                  Insert from parsed Nme field
FnlDest                      varchar                  Insert from parsed Nme field  
ShipDte                      varchar                  Insert from parsed Nme field

thanks,
0
Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

 

Author Comment

by:malc77
Comment Utility
Greetings Experts,

Sorry for the delay in response...I will try the solutions provided above today.  thanks for your patience.
0
 

Author Comment

by:malc77
Comment Utility
Greetings LandyJ,

Thanks for your response this is a great solution.

Each row has a unique key field 'RefDocNo' already assigned.  Is it possible to make this field the rowid?

Sorry for not mentioning it in the beginning.

Thanks,
0
 
LVL 7

Expert Comment

by:LandyJ
Comment Utility
Sure, it doesn't matter what the rowID field is.  The important one is the colID identity field.  That's the one that will sort the split-out rows into the correct columns.  By using the RefDocNo as the rowID in #Pivot, it will let you join the two tables to get your final result:

SELECT
      AuxAcctAsmnt_1,
      CostCtr,
      CostElem,
      Cost,
      Col01,
      Col02,
      Col03,
      Col04,
      Col05,
      Col06,
      Col07,
      Col08,
      Col09,
      Col10,
      RefDocNo,
      Per,
      User,
      ValueObjCurr ,
      DocDate,
      PostingDate,
      Mde,
      SrvTyp,
      Supplier,
      Origin,
      Quantity,
      Material,
      ActlWght,
      DimWght ,
      FnlDest,
      ShipDte
FROM
      MyTable mt
      INNER JOIN #Pivot t ON mt.RefDocNo = t.RefDocNo


hth,
Landy
0
 

Author Comment

by:malc77
Comment Utility
Greetings,

Thanks for your assistance....This has increase my abilities as a developing DBA.

Malcolm
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Suggested Solutions

Slowly Changing Dimension Transformation component in data task flow is very useful for us to manage and control how data changes in SSIS.
The Delta outage: 650 cancelled flights, more than 1200 delayed flights, thousands of frustrated customers, tens of millions of dollars in damages – plus untold reputational damage to one of the world’s most trusted airlines. All due to a catastroph…
Via a live example, show how to backup a database, simulate a failure backup the tail of the database transaction log and perform the restore.
Viewers will learn how the fundamental information of how to create a table.

772 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now