7

I've a table with entries like this.

    MachineName
-----------------------

    Ab bb zecos
    a zeng
    zeng
    empty

4 rows in a table.

How can i seperate those 4 rows to get output like.

       M1       M2       M3
-----------------------------------
       Ab       bb      zecos
       a        zeng     NULL
       zeng     NULL     NULL
       NULL     NULL     NULL
6
  • 1
    This isn't by chance so you can apply tags to elements, would it? Commented Jun 25, 2012 at 7:50
  • @BradChristie Didn't get you! Commented Jun 25, 2012 at 7:53
  • 1
    As in you didn't understand the question? I'm asking if you're primary purpose is to apply tags to items (almost like a blog does to posts) and now you're trying to retrieve them back. Commented Jun 25, 2012 at 7:57
  • Maybe this post will help: http://stackoverflow.com/questions/2647/split-string-in-sql Commented Jun 25, 2012 at 8:39
  • Create a temp table with M1, M2, M3 columns, get machine names, split names by spaces and insert row the in a new table Commented Jun 25, 2012 at 8:44

5 Answers 5

12

Instead of using split function there is a function called ParseName which returns the specified part of the object which spilts the string delimated by . Please go through the ParseName link which helped me in writing this query

Declare @Sample Table
(MachineName varchar(max))

Insert into @Sample
values 
('Ab bb zecos'),('a Zeng')


  SELECT 
  Reverse(ParseName(Replace(Reverse(MachineName), ' ', '.'), 1)) As [M1]
 , Reverse(ParseName(Replace(Reverse(MachineName), ' ', '.'), 2)) As [M2]
 , Reverse(ParseName(Replace(Reverse(MachineName), ' ', '.'), 3)) As [M3]

  FROM  (Select MachineName from @Sample
  ) As [x] 
Sign up to request clarification or add additional context in comments.

4 Comments

I recall something about PARSENAME not allowing more than 4 items (since it's used for object names and 4 parts is the maximum length of an object identifier) - so you could use this as long as you remember that :)
Yeah thanks for reminding me but i think OP mentioned in his question having only 3 columns
perfect... this is what i also exactly want.. thanks a ton :)
If segments of the split are blank you may get no returned result for all of the segments. To avoid this I do the following (I use + as its not in the column but you can use any unused character): Replace(ParseName(Replace(DELADD.CONTACT_VALUE, CHAR(10), '+.+'), 3),'+','')
6

Try this one:

    CREATE FUNCTION [dbo].[SplitIndex](@Delimiter varchar(20) = ' ', @Search varchar(max), @index int)
    RETURNS varchar(max)
    AS
    BEGIN
          DECLARE @ix int,
                      @pos int,
                    @rt varchar(max)

          DECLARE @tb TABLE (Val varchar(max), id int identity(1,1))

          SET @ix = 1
          SET @pos = 1


          WHILE @ix <= LEN(@search) + 1 BEGIN

                SET @ix = CHARINDEX(@Delimiter, @Search, @ix)

                IF @ix = 0
                      SET @ix = LEN(@Search)
                ELSE
                      SET @ix = @ix - 1

                INSERT INTO @tb
                SELECT SUBSTRING(@Search, @pos, @ix - @pos + 1)

                SET @ix = @ix + 2
                SET @pos = @ix
          END

          SELECT @Rt = Val FROM @Tb WHERE id = @index
          RETURN @Rt     
    END

Use like so:

SELECT dbo.SplitIndex(' ', 'hello World', 1)

Combine that with Dems answer and you should be good to go

(Note it will return NULL if the specified index does not exist)

e.g.

SELECT dbo.SplitIndex(' ', 'Hello World', 3)  

would return NULL because index 3 does not exist

Not sure what performance is like though, I just modified a table valued split function that I'd done so it might be worth rewriting to be more like the MySql version

1 Comment

Thank you, you saved me, this is the best solution. All above answer using PARSENAME has a drawback, of limitation no more then 4 values
4

Use Parsename() function

with cte as(
    select 'Aria Karimi' as FullName
    Union
    select 'Joe Karimi' as FullName
    Union
    select 'Bab Karimi' as FullName
)

SELECT PARSENAME(REPLACE(FullName,' ','.'),2) as Name, PARSENAME(REPLACE(FullName,' ','.'),1) as Family from cte

Result

Name    Family
-----   ------
Aria    Karimi
Bab     Karimi
Joe     Karimi

Comments

2
DECLARE @Tmp TABLE (empid INT,joined nchar(10))

INSERT @Tmp SELECT 1,'1990, 1111' 
INSERT @Tmp SELECT 2,'2000, 2222' 

INSERT @Tmp SELECT 3,'1993, 3333' 

INSERT @Tmp SELECT 4,'1899, 4444' 
INSERT @Tmp SELECT 5,'1999, 5555' 

INSERT @Tmp SELECT 6,'2001, 6666 ' 


--Using PARSENAME 

SELECT empid, joined,
       PARSENAME(REPLACE(joined,',','.'),2) join1, 
       PARSENAME(REPLACE(joined,',','.'),1) join2 
FROM @Tmp

Comments

-7

If you are programming in C++, please do:

#include <cstring>
#include <iomanip>

using namespace std;
int main () {
string machine[12];
for (int i = 0; i < 12; i++) {
    if (machine[i] == "")
        machine[i] = "NULL";
}

for (int i = 0; i < 3; i++) {
    cout << setw(10) << machine[i] << setw(10) << machine[i+1] << setw(10) << machine[i+2] << endl;
}
return 1;
}

3 Comments

No c++ tags on this post, isn't this a bit of a guess?
Do you honestly propose solving a database query by extracting every record from the DB, processing it in C++, and then pushing everything back to the DB? Really?
Sounds like a horror story from TheDailyWTF to me :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.