Michael Born
Michael Born

Reputation: 799

Need help to write a SQL query?

I have a SQL table with column which contain string like 'type|type1|type2|type3|type4'. I need to select the string, id. Split string and insert to another table. First item should be default and I need to get identity of it and insert to another table with the type value.

Please help me to create T-SQL query to accomplish desirable result.

Example

Step 1 To select Items from Table 1.
Step 2 Split to array
Step 3 Insert to Table 2 (first item will be default)
Step 4 Update Table 1 with default Type Value based on TypeID and Default True

Table 1

ID       Items                           Default
--------------------------------------------------
1        type|type1|type2|type3|type4
2        type|type1|type2|type3|type4

Table 2

ID   TypeID        Type    Default(bool)
--------------------------------------------------
1    1             type1   1
2    1             type2   0

Upvotes: 1

Views: 171

Answers (2)

Conrad Frix
Conrad Frix

Reputation: 52645

Using the split function from Arnold Fribble's answer on this thread

Create FUNCTION dbo.Split (@sep char(1), @s varchar(512))
RETURNS table
AS
RETURN (
    WITH Pieces(pn, start, stop) AS (
      SELECT 1, 1, CHARINDEX(@sep, @s)
      UNION ALL
      SELECT pn + 1, stop + 1, CHARINDEX(@sep, @s, stop + 1)
      FROM Pieces
      WHERE stop > 0
    )
    SELECT pn,
      SUBSTRING(@s, start, CASE WHEN stop > 0 THEN stop-start ELSE 512 END) AS s
    FROM Pieces
  )
GO

You can write the following (I made some guesses about the ID field in table2 and what the defaultTypeID should be in table1 but you should be able to adjust that)

CREATE TABLE #table1       ( 
     id            INT, 
     items         VARCHAR(MAX), 
     defaulttypeid INT 
  ) 

CREATE TABLE #table2       ( 
     id        INT IDENTITY, 
     typeid    INT, 
     TYPE      VARCHAR(5), 
     isdefault BIT 
  ) 

INSERT INTO #table1 
VALUES      (1, 
             'type|type1|type2|type3|type4', 
             NULL), 
            (2, 
             'type|type1|type2|type3|type4', 
             NULL) 


INSERT INTO #table2 
            (typeid, 
             TYPE, 
             isdefault) 
SELECT id             typeid, 
       Rtrim(split.s) AS item, 
       CASE 
         WHEN ( split.pn = 1 ) THEN 1 
         ELSE 0 
       END            AS isdefault 
FROM   #table1 
       CROSS APPLY test.dbo.Split('|', items) AS split 

UPDATE #table1 
SET    defaulttypeid = t2.ID
FROM   #table1 t1 
       INNER JOIN #table2 t2 
         ON t1.id = t2.typeid 
            AND t2.isdefault = 1 


DROP TABLE #table1 

DROP TABLE #table2 

This outputs

ID          Items                          DefaultTypeID
----------- ------------------------------ -------------
1           type|type1|type2|type3|type4    1     
2           type|type1|type2|type3|type4    6



ID          TypeID      Type  IsDefault
----------- ----------- ----- ---------
1           1           type  1
2           1           type1 0
3           1           type2 0
4           1           type3 0
5           1           type4 0
6           2           type  1
7           2           type1 0
8           2           type2 0
9           2           type3 0
10          2           type4 0

Upvotes: 2

Ash Burlaczenko
Ash Burlaczenko

Reputation: 25435

Though I totally disagree with the use of cursors I can't think of another way. This solution isn't tested but It looks like it should be ok.

DECLARE @pos INT
DECLARE @id INT
DECLARE @string VARCHAR(MAX)
DECLARE @default INT
DECLARE @substring VARCHAR(MAX)

DECLARE tempCursor CURSOR FOR
SELECT id, string
    FROM table_name

OPEN tempCursor;
FETCH NEXT FROM tempCursor
    INTO @id, @string

WHILE @@FETCH_STATUS = 0
BEGIN
SET @default = 1
SET @pos = CHARINDEX('|', @string)
WHILE (@pos <> 0)
BEGIN
    SET @substring = SUBSTRING(@string, 1, @pos - 1)
    INSERT INTO table_name2(typeid, type, default) VALUES (@id, @substring, @default)
    SET @string = substring(@string, @pos+1, LEN(@string))
    SET @pos = charindex('|', @string)
    SET @default = 0
END

FETCH NEXT FROM tempCursor
    INTO @id, @string
END

CLOSE EWSCursor;
DEALLOCATE EWSCursor;

Hope this helps.

Upvotes: 2

Related Questions