Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

Parse single field into multiple columns

Posted on 2006-10-24
8
Medium Priority
?
669 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
8 Comments
 
LVL 10

Expert Comment

by:AaronAbend
ID: 17797986
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
ID: 17798151
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 2000 total points
ID: 17799137
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
Fill in the form and get your FREE NFR key NOW!

Veeam® is happy to provide a FREE NFR server license to certified engineers, trainers, and bloggers.  It allows for the non‑production use of Veeam Agent for Microsoft Windows. This license is valid for five workstations and two servers.

 

Author Comment

by:malc77
ID: 17799418
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
 

Author Comment

by:malc77
ID: 17833925
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
ID: 17834586
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
ID: 17834702
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
ID: 17837020
Greetings,

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

Malcolm
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

A Stored Procedure in Microsoft SQL Server is a powerful feature that it can be used to execute the Data Manipulation Language (DML) or Data Definition Language (DDL). Depending on business requirements, a single Stored Procedure can return differe…
Windocks is an independent port of Docker's open source to Windows.   This article introduces the use of SQL Server in containers, with integrated support of SQL Server database cloning.
Familiarize people with the process of utilizing SQL Server functions from within Microsoft Access. Microsoft Access is a very powerful client/server development tool. One of the SQL Server objects that you can interact with from within Microsoft Ac…
Using examples as well as descriptions, and references to Books Online, show the documentation available for date manipulation functions and by using a select few of these functions, show how date based data can be manipulated with these functions.

610 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