• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1282
  • Last Modified:

Parse multi-column array in sql stored procedure using a pivot (numbers) table

In order to parse an array passed in as a parameter in a stored procedure I use a stored procedure ripped from here: http://vyaskn.tripod.com/passing_arrays_to_stored_procedures.htm
To be more precise, it is method 5:
SELECT o.OrderID, CustomerID, EmployeeID, OrderDate
      FROM dbo.Orders AS o
      JOIN
      (
            
            SELECT LTRIM(RTRIM(SUBSTRING(OrderID, number+1, CHARINDEX(',', OrderID, number+1)-number - 1))) AS OrderID
            FROM      
            (
                  SELECT ',' + @OrderList + ',' AS OrderID
            ) AS InnerQuery
            JOIN
            Numbers n
            ON
            n.Number < LEN(InnerQuery.OrderID)
            WHERE SUBSTRING(OrderID, number, 1) = ','
      ) as Derived
      ON o.OrderID = Derived.OrderID
I use this sp to insert records in a table and instead of one column per insert (row) I need to do more.
For example, my input string would be something like:
col1_val1,col2_val1,col3_val1,col1_val2,col2_val2,col3_val2,col1_val3,col2_val3,col3_val3 ....
However, I can't get my head around how to build this query. I have tried a cross join to multiple Numbers table but that generates a cartesian product (I cannot get a distinct-like result).
Is there any way around it?
Thanks
0
daniel_balla
Asked:
daniel_balla
  • 4
  • 2
1 Solution
 
Rajesh_mjCommented:
Hi,
First create dbo.SplitOrderIDs specified in the method 6
 http://vyaskn.tripod.com/passing_arrays_to_stored_procedures.htm

Then just try this:

(I have used orderid,ShipVia,EmployeeID as three columns ).



declare @OrderList varchar(1000),@Col1 varchar(1000),@Col2 varchar(1000),@Col3 varchar(1000)
SET @OrderList ='10248,3,5,10259,3,4'


drop table #newtable

Select  IDENTITY(int, 1,1) AS ID_Num, OrderID INTO  #NewTable from dbo.SplitOrderIDs(@OrderList)
select * from #NewTable

Select @col1 = '',@col2 = '',@Col3 =''

select @Col1 =@Col1+cast(OrderID as varchar(10))+',' from #NewTable where Id_Num % 3 = 1
select @Col2 =@Col2+cast(OrderID as varchar(10))+',' from #NewTable where Id_Num % 3 = 2
select @Col3 =@Col3+cast(OrderID as varchar(10))+',' from #NewTable where Id_Num % 3 = 0

SELECT Distinct o.OrderID, CustomerID, EmployeeID, OrderDate
      FROM dbo.Orders AS o
      JOIN
      (
           
            SELECT LTRIM(RTRIM(SUBSTRING(Column1, number+1, CHARINDEX(',', Column1, number+1)-number - 1))) AS Column1
            FROM      
            (
                  SELECT ',' + @col1 + ',' AS Column1
            ) AS InnerQuery
            JOIN
            Numbers n
            ON
            n.Number < LEN(InnerQuery.Column1)
            WHERE SUBSTRING(Column1, number, 1) = ','

      ) as Derived1

      ON o.OrderID = Derived1.Column1

      JOIN
      (
           
            SELECT LTRIM(RTRIM(SUBSTRING(Column2, number+1, CHARINDEX(',', Column2, number+1)-number - 1))) AS Column2
            FROM      
            (
                  SELECT ',' + @col2 + ',' AS Column2
            ) AS InnerQuery
            JOIN
            Numbers n
            ON
            n.Number < LEN(InnerQuery.Column2)
            WHERE SUBSTRING(Column2, number, 1) = ','

      ) as Derived2

      ON o.ShipVia = Derived2.Column2
 JOIN
      (
           
            SELECT LTRIM(RTRIM(SUBSTRING(Column3, number+1, CHARINDEX(',', Column3, number+1)-number - 1))) AS Column3
            FROM      
            (
                  SELECT ',' + @col3 + ',' AS Column3
            ) AS InnerQuery
            JOIN
            Numbers n
            ON
            n.Number < LEN(InnerQuery.Column3)
            WHERE SUBSTRING(Column3, number, 1) = ','

      ) as Derived3

      ON o.EmployeeID = Derived3.Column3



0
 
daniel_ballaAuthor Commented:
Fair enough, but as far as I can see the idea is to use the pivot table instead of the expensive string parsing (such as the specified UDF does) to optimize the whole process.
How is the proposed method any better than just parsing the string (using a while and the substring) and doing the inserts in the while loop?
do you reckon there is no way it can be done just using the join to the numbers table (so no loop around to parse the string)?
0
 
Rajesh_mjCommented:
Hi,
Just try: (Hope that it is some thing more better)

Declare @OrderList varchar(1000)
SET @OrderList ='10248,3,5,10259,3,4'

SELECT Distinct o.OrderID, CustomerID, EmployeeID, OrderDate
      FROM dbo.Orders AS o
      JOIN
      (
           
            SELECT LTRIM(RTRIM(SUBSTRING(OrderID, number+1, CHARINDEX(',', OrderID, number+1)-number - 1))) AS OrderID,
(LEN(SUBSTRING(OrderID,1,number+1)) -
            LEN(REPLACE(SUBSTRING(OrderID,1,number+1), ',', ''))) /
            LEN(',') as Num

            FROM      
            (
                  SELECT ',' + @OrderList + ',' AS OrderID
            ) AS InnerQuery
            JOIN
            Numbers n
            ON
            n.Number < LEN(InnerQuery.OrderID)
            WHERE SUBSTRING(OrderID, number, 1) = ','
      ) as Derived
      ON o.OrderID = CASE WHEN Derived.Num % 3 = 1 THEN Derived.OrderID END
 JOIN
      (
           
            SELECT LTRIM(RTRIM(SUBSTRING(OrderID, number+1, CHARINDEX(',', OrderID, number+1)-number - 1))) AS OrderID,
(LEN(SUBSTRING(OrderID,1,number+1)) -
            LEN(REPLACE(SUBSTRING(OrderID,1,number+1), ',', ''))) /
            LEN(',') as Num

            FROM      
            (
                  SELECT ',' + @OrderList + ',' AS OrderID
            ) AS InnerQuery
            JOIN
            Numbers n
            ON
            n.Number < LEN(InnerQuery.OrderID)
            WHERE SUBSTRING(OrderID, number, 1) = ','
      ) as Derived1
      ON o.ShipVia = CASE WHEN Derived1.Num % 3 = 2 THEN Derived1.OrderID END
JOIN
      (
           
            SELECT LTRIM(RTRIM(SUBSTRING(OrderID, number+1, CHARINDEX(',', OrderID, number+1)-number - 1))) AS OrderID,
(LEN(SUBSTRING(OrderID,1,number+1)) -
            LEN(REPLACE(SUBSTRING(OrderID,1,number+1), ',', ''))) /
            LEN(',') as Num

            FROM      
            (
                  SELECT ',' + @OrderList + ',' AS OrderID
            ) AS InnerQuery
            JOIN
            Numbers n
            ON
            n.Number < LEN(InnerQuery.OrderID)
            WHERE SUBSTRING(OrderID, number, 1) = ','
      ) as Derived2
      ON o.EmployeeID = CASE WHEN Derived2.Num % 3 = 0 THEN Derived2.OrderID END
0
Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

 
Rajesh_mjCommented:
Hi,
Using temp table:
Declare @OrderList varchar(1000)
SET @OrderList ='10248,3,5,10259,3,4'


            SELECT LTRIM(RTRIM(SUBSTRING(OrderID, number+1, CHARINDEX(',', OrderID, number+1)-number - 1))) AS OrderID,
(LEN(SUBSTRING(OrderID,1,number+1)) -
            LEN(REPLACE(SUBSTRING(OrderID,1,number+1), ',', ''))) /
            LEN(',') as Num
            INTO #tmp
            FROM      
            (
                  SELECT ',' + @OrderList + ',' AS OrderID
            ) AS InnerQuery
            JOIN
            Numbers n
            ON
            n.Number < LEN(InnerQuery.OrderID)
            WHERE SUBSTRING(OrderID, number, 1) = ','


SELECT Distinct o.OrderID, CustomerID, EmployeeID, OrderDate
      FROM dbo.Orders AS o
      JOIN
       #tmp as Derived
      ON o.OrderID = CASE WHEN Derived.Num % 3 = 1 THEN Derived.OrderID END
 JOIN
      #tmp as Derived1
      ON o.ShipVia = CASE WHEN Derived1.Num % 3 = 2 THEN Derived1.OrderID END
JOIN
     #tmp Derived2
      ON o.EmployeeID = CASE WHEN Derived2.Num % 3 = 0 THEN Derived2.OrderID END
0
 
Rajesh_mjCommented:
Hi,
I have taken Count String Occurrence Function from
 http://www.sql-server-helper.com/functions/count-string.aspx
0
 
daniel_ballaAuthor Commented:
Thanks Rajesh. This might be the magic I need. Let me give it a try.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

  • 4
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now