Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 General SQL Server Forums
 New to SQL Server Programming
 SUBSTRING

Author  Topic 

xhostx
Constraint Violating Yak Guru

277 Posts

Posted - 2012-07-19 : 08:21:38
Hi,

I need to extract the third values of all the lines from a column:

AAAA BBBB KKKK GGGG
LLLL BBBB HHHH WWWWWSDR
HHHH BBBB DDDDD XXXXX

hint: there's always a value BBBB and the number of spaces between the BBBB values and the third values is always 4.

outcome:

KKKK
HHHH
DDDDD

Any help will be appreciated.

Thanks,

--------------------------
Get rich or die trying
--------------------------

sunitabeck
Master Smack Fu Yak Hacker

5155 Posts

Posted - 2012-07-19 : 08:43:45
Please feel free to laugh at me, I couldn't think of anything simpler:
DECLARE @x VARCHAR(32);
SET @x = 'AAAA BBBB KKKK GGGG';
SELECT
STUFF
(
STUFF
(
STUFF(@x,1,CHARINDEX(' ',@x),''),
1,
CHARINDEX(' ',STUFF(@x,1,CHARINDEX(' ',@x),'')),
''
),
CHARINDEX
( ' ',
STUFF
(
STUFF(@x,1,CHARINDEX(' ',@x),''),
1,
CHARINDEX(' ',STUFF(@x,1,CHARINDEX(' ',@x),'')),
''
)
), LEN(@x),''
);
But, in my defense, it is a lot of copy and paste, and is simpler than it looks. We really need regular expressions in SQL Server!
Go to Top of Page

khtan
In (Som, Ni, Yak)

17689 Posts

Posted - 2012-07-19 : 08:46:34
[code]
select *, substring(col, start, charindex(' ', col, start) - start)
from
(
select *, start = charindex('BBBB', col) + 4 + 4
from yourtable
) t
[/code]


KH
[spoiler]Time is always against us[/spoiler]

Go to Top of Page

sunitabeck
Master Smack Fu Yak Hacker

5155 Posts

Posted - 2012-07-19 : 08:47:29
Hah! I knew there was something simpler. I had missed the constant BBBB in the specification.

In my own defense, mine is more general
Go to Top of Page

khtan
In (Som, Ni, Yak)

17689 Posts

Posted - 2012-07-19 : 08:50:03
quote:
Originally posted by sunitabeck

Hah! I knew there was something simpler. I had missed the constant BBBB in the specification.

In my own defense, mine is more general



But your query is prettier .

It can be even simpler to use a ready make string parsing function like SwePeso's fnParseString()


KH
[spoiler]Time is always against us[/spoiler]

Go to Top of Page

xhostx
Constraint Violating Yak Guru

277 Posts

Posted - 2012-07-19 : 09:26:49
thank you a lot sunitabeck and khtan.

@khtan your query seems to be simpler but I think the end result is blank! I tried resolving it but no luck.

@sunitabeck, yours works perfect when but when I add a space or 2 before BBBB it fails.

I just want to highlight that the spaces before and after are 4.

this is what I have tried:
select *, substring(ltrim(rtrim(value1)), start, charindex(' ', ltrim(rtrim(value1)), start) - start) As EndResult
from
(
select *, start = charindex('BBBB', ltrim(rtrim(value1))) + 4 + 4
from mytable
where value1 like '%STRING%'
) t

--------------------------
Get rich or die trying
--------------------------
Go to Top of Page

khtan
In (Som, Ni, Yak)

17689 Posts

Posted - 2012-07-19 : 09:29:49
[code]where value1 like '%STRING%'[/code]

what is that condition for ? I don't see the word "STRING" in your sample data


KH
[spoiler]Time is always against us[/spoiler]

Go to Top of Page

xhostx
Constraint Violating Yak Guru

277 Posts

Posted - 2012-07-19 : 09:39:54
the condition is part of the whole string

e.g:

AAAA BBBB KKKK GGGG
LLLL BBBB HHHH GGGG
HHHH BBBB DDDDD GGGG

I compare the above values with incoming values from another table. but this is more of select just few rows I need for a comparison purpose.

The generic format of the whole string is that ALL rows will have BBBB.
The spaces between 1st 2nd and 3rd strings is 4 spaces, after 3rd string there's only 3 spaces.

e.g:

AAAA----BBBB----KKKK---GGGG
LLLL----BBBB----HHHH---GGGG
HHHH----BBBB----DDDDD---GGGG.

Hope this help.

Thank you all



--------------------------
Get rich or die trying
--------------------------
Go to Top of Page

khtan
In (Som, Ni, Yak)

17689 Posts

Posted - 2012-07-19 : 09:47:58
any result for the following query ?

select *
from mytable
where value1 like '%STRING%'



KH
[spoiler]Time is always against us[/spoiler]

Go to Top of Page

Transact Charlie
Master Smack Fu Yak Hacker

3451 Posts

Posted - 2012-07-19 : 09:50:05
a trick -- if the strings are shorter than 128 characters

DECLARE @sample TABLE ([value] VARCHAR(128))
INSERT @sample ([value])
VALUES ('AAAA BBBB KKKK GGGG')
, ('LLLL BBBB HHHH WWWWWSDR')
, ('HHHH BBBB DDDDD XXXXX')

SELECT [value], PARSENAME(REPLACE([value], ' ', '.'), 2) FROM @sample

Or as Khtan mentioned -- use Peso's fnParseString()

Transact Charlie
Msg 3903.. The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION.
http://nosqlsolution.blogspot.co.uk/
Go to Top of Page

xhostx
Constraint Violating Yak Guru

277 Posts

Posted - 2012-07-19 : 10:03:21
@Khan, that was just sample. but it will generate results if the '%STRING%' matches some value in the column.

@Transact Charlie. Your trick works perfect but, when I plug it to my physical table it returns NULLs.

Any work around please?

--------------------------
Get rich or die trying
--------------------------
Go to Top of Page

khtan
In (Som, Ni, Yak)

17689 Posts

Posted - 2012-07-19 : 10:19:20
can you post some of the the actual data ? Don't replace the space with dash or any other characters. And enclosed it in [code] tag.


KH
[spoiler]Time is always against us[/spoiler]

Go to Top of Page

xhostx
Constraint Violating Yak Guru

277 Posts

Posted - 2012-07-19 : 10:25:30
This is coming from a the original data




currentversion REG_SZ 4.0 CCMPHDB2
currentversion REG_SZ K23 CCMPHDMDB
currentversion REG_SZ 5.2 CCMPHDMVL
currentversion REG_SZ 1E2 CCMPHDSDB1




result:

4.0
E23
5.2
1E2

--------------------------
Get rich or die trying
--------------------------
Go to Top of Page

jleitao
Posting Yak Master

100 Posts

Posted - 2012-07-19 : 10:40:08
like sunitabeck say this is probably not the better way:

declare @test nvarchar(1000)
set @test = 'currentversion REG_SZ 5.2 FFEEEEEEE'


select
RTRIM(LEFT( REVERSE( RTRIM(LEFT(@test, len(@test) - charindex( ' ', REVERSE( @test))))),CHARINDEX( ' ', REVERSE( RTRIM(LEFT(@test, len(@test) - charindex( ' ', REVERSE( @test))))))))


------------------------
PS - Sorry my bad english
Go to Top of Page

jleitao
Posting Yak Master

100 Posts

Posted - 2012-07-19 : 10:41:37
upss... forgot the last reverse:

declare @test nvarchar(1000)
set @test = 'currentversion REG_SZ 5.2 FFEEEEEEE'


select
REVERSE(RTRIM(LEFT( REVERSE( RTRIM(LEFT(@test, len(@test) - charindex( ' ', REVERSE( @test))))),CHARINDEX( ' ', REVERSE( RTRIM(LEFT(@test, len(@test) - charindex( ' ', REVERSE( @test)))))))))

------------------------
PS - Sorry my bad english
Go to Top of Page

xhostx
Constraint Violating Yak Guru

277 Posts

Posted - 2012-07-19 : 10:52:37
In case of more than one space, it doesn't work!!

it works when there's only one space.





--------------------------
Get rich or die trying
--------------------------
Go to Top of Page

xhostx
Constraint Violating Yak Guru

277 Posts

Posted - 2012-07-19 : 10:58:37
I have came out with the following:

select substring(ltrim(rtrim(value1)), patindex('%REG_SZ%',ltrim(rtrim(value1)))+10,100)
from import

Output:

7.8   ABCDEFG
K123 ACBDNCDR
E345 ULTOIU


Can someone built on this and help me get the following result:

eg:
7.8
K123
E345

Thank you.

--------------------------
Get rich or die trying
--------------------------
Go to Top of Page

khtan
In (Som, Ni, Yak)

17689 Posts

Posted - 2012-07-19 : 11:00:14
well, this works for me

; with tbl as
(
select col = ' currentversion REG_SZ 4.0 CCMPHDB2 ' union all
select col = ' currentversion REG_SZ K23 CCMPHDMDB ' union all
select col = ' currentversion REG_SZ 5.2 CCMPHDMVL ' union all
select col = ' currentversion REG_SZ 1E2 CCMPHDSDB1 '
)
select col, word = substring(col, start, charindex(' ', col, start) - start)
from
(
select *, start = charindex('REG_SZ', col) + 6 + 4
from tbl
) t


col word
------------------------------------------------- -------------------------------------------------
currentversion REG_SZ 4.0 CCMPHDB2 4.0
currentversion REG_SZ K23 CCMPHDMDB K23
currentversion REG_SZ 5.2 CCMPHDMVL 5.2
currentversion REG_SZ 1E2 CCMPHDSDB1 1E2

(4 row(s) affected)


Note : you only need the part in blue

KH
[spoiler]Time is always against us[/spoiler]

Go to Top of Page

xhostx
Constraint Violating Yak Guru

277 Posts

Posted - 2012-07-19 : 11:05:16
quote:
Originally posted by khtan

well, this works for me

; with tbl as
(
select col = ' currentversion REG_SZ 4.0 CCMPHDB2 ' union all
select col = ' currentversion REG_SZ K23 CCMPHDMDB ' union all
select col = ' currentversion REG_SZ 5.2 CCMPHDMVL ' union all
select col = ' currentversion REG_SZ 1E2 CCMPHDSDB1 '
)
select col, word = substring(col, start, charindex(' ', col, start) - start)
from
(
select *, start = charindex('REG_SZ', col) + 6 + 4
from tbl
) t


col word
------------------------------------------------- -------------------------------------------------
currentversion REG_SZ 4.0 CCMPHDB2 4.0
currentversion REG_SZ K23 CCMPHDMDB K23
currentversion REG_SZ 5.2 CCMPHDMVL 5.2
currentversion REG_SZ 1E2 CCMPHDSDB1 1E2

(4 row(s) affected)


Note : you only need the part in blue

KH
[spoiler]Time is always against us[/spoiler]





Thanks a lot.

I have came out with another solution too:

select substring(t.ab,1, charindex(' ',t.ab))
from (
select substring(ltrim(rtrim(value1)), patindex('%REG_SZ%',ltrim(rtrim(value1)))+10,100) as ab
from import ) t


Thanks to All of you guys

--------------------------
Get rich or die trying
--------------------------
Go to Top of Page

Transact Charlie
Master Smack Fu Yak Hacker

3451 Posts

Posted - 2012-07-19 : 11:12:09
lets try something else! A splitter function and a set based loop...... There is almost certainly a better way but this way is cunning!

BEGIN TRAN

USE tempdb
GO
IF EXISTS ( SELECT 1 FROM sys.objects WHERE [name] = 'split' AND [schema_id] = SCHEMA_ID('dbo'))
DROP FUNCTION dbo.Split
GO

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

DECLARE @sample TABLE (
[SampleID] INT
, [Text] VARCHAR(MAX)
)
INSERT @sample VALUES
(1, 'currentversion REG_SZ 4.0 CCMPHDB2 ')
, (2, 'currentversion REG_SZ K23 CCMPHDMDB ')
, (3, 'currentversion REG_SZ 5.2 CCMPHDMVL ')
, (4, 'currentversion REG_SZ 1E2 CCMPHDSDB1 ')

-- trim the data
DECLARE @DataCleaned TABLE ([SampleID] INT, [Text] VARCHAR(MAX))
INSERT @DataCleaned ([SampleID], [Text]) SELECT [SampleID], [Text] FROM @Sample

DECLARE @rowCount INT = 1
WHILE @rowCount > 0
BEGIN
UPDATE @DataCleaned SET [Text] = LTRIM(RTRIM(REPLACE([Text], ' ', ' '))) WHERE [Text] LIKE '% %'
SET @rowCount = @@ROWCOUNT
END

SELECT [SampleID], split.*
FROM
@DataCleaned AS dc
CROSS APPLY dbo.Split (' ', dc.[Text]) AS split
WHERE
split.[pn] = 3

ROLLBACK


Results:

SampleID pn s
1 3 4.0
2 3 K23
3 3 5.2
4 3 1E2




Transact Charlie
Msg 3903.. The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION.
http://nosqlsolution.blogspot.co.uk/
Go to Top of Page
   

- Advertisement -