SQL Server select part of string - sql

I have table like this
Column1
-------------------------------------------------------
nn=APPLE IPod 44454,o=0006,o=TOP8,nn=USA,nn=TOP8+
nn=SAMSUNG G5 487894,o=04786,o=T418,nn=JPN,nn=TO478+
And I need update that table and get result like this
Column1 Column2
---------------------------------------------------------------
nn=APPLE IPod 44454,o=0006,o=TOP8,nn=USA,nn=TOP8+ 44454
nn=SAMSUNG G5 487894,o=04786,o=T418,nn=JPN,nn=TO478+ 487894
My idea is but I can not fit with first character:
update tablename
set [column2] = SUBSTRING(column1, 1, CHARINDEX(' ', column1) - 1 (column1, CHARINDEX(' ', column1) + 1, LEN(column1))

This query can help you.
UPDATE tablename SET [column2] =
SUBSTRING((LEFT(column1,CHARINDEX(',',column1)-1)), CHARINDEX(' ', column1, CHARINDEX(' ',column1) +1 ) +1 ,LEN(column1))

Okay, given the second sample record, it looks like what you need is the last element of the space-delimited string in the first position of the comma-delimited string. So write yourself (or find) a string-splitter function that accepts a string and a delimiter, and then your parsing logic is:
split the field at the commas
take the first element
split that element at the spaces
take the last element
Does that make sense?

The following answer is based only on the two records you actually showed us. If we were to derive a rule from this, it might be that we want to extract the previous word (a product number) occurring immediately before the first comma in the string. If so, then we can try the following logic:
isolate the substring before the comma (e.g. nn=APPLE Ipod 44454)
reverse that string (45444 dopI ELPPA=nn)
then take the substring of that before the first space (45444)
finally reverse this substring to yield the product number we want (44454)
Consider the following query, with data imported via a CTE:
WITH yourTable AS (
SELECT 'nn=APPLE IPod 44454,o=0006,o=TOP8,nn=USA,nn=TOP8+' AS column1 UNION ALL
SELECT 'nn=SAMSUNG G5 487894,o=04786,o=T418,nn=JPN,nn=TO478+'
),
update_cte AS (
SELECT
column1,
column2,
REVERSE(
SUBSTRING(REVERSE(SUBSTRING(column1, 1, CHARINDEX(',', column1)-1)),
1,
CHARINDEX(' ', REVERSE(SUBSTRING(column1, 1, CHARINDEX(',', column1)-1))) - 1)
) AS col2
FROM yourTable
)
SELECT column1, col2 FROM update_cte;
Output:
Demo here:
Rextester
If you wanted to update your table to bring in these column2 product IDs, then you can use the above CTE fairly easily:
UPDATE update_cte
SET column2 = col2;

Related

T-SQL splitting column on a delimiter [duplicate]

This question already has answers here:
T-SQL split string
(27 answers)
Closed 4 years ago.
I have a column with three groups data delimited by a forward slash, like so
AB/1234/10
The column is always formatted the same in every row, with 2 characters, a slash, some number of characters, a slash, and then 2 more characters. I need to split this one column into three. So the above example becomes
Column1 Column2 Column3
AB 1234 10
I'm not quite sure how to go about this. I've been using SELECT SUBSTRING but that isn't quite giving me what I need.
select SUBSTRING(MyColumn, 1, CHARINDEX('/', MyColumn, 1)-1)
FROM MyTable
Will return AB, and that's great. But I can't wrap my mind around how to grab the middle and the end sections. I thought that
select SUBSTRING(MyColumn, 4, CHARINDEX('/', MyColumn, 4))
FROM MyTable
Would work in grabbing the middle, but it returns 1234/10
I hope my question is clear and I would appreciate any advice pointing me in the right direction, Thank you.
You can work with fixed offsets, since you defined that the string always starts with two, and ends with two characters.
Here is a full working example:
DECLARE #tmp TABLE (
Merged nvarchar(max)
)
INSERT INTO #tmp SELECT N'AB/1234/10'
INSERT INTO #tmp SELECT N'AB/ANYNUMBEROF-CHARACTERS/10'
SELECT
LEFT(Merged,2) AS Column1,
SUBSTRING(Merged,4,LEN(Merged)-6) AS Column2,
RIGHT(Merged,2) AS Column3
FROM #tmp
We subtract the length of the string minus a constant (6 = two chars left, two chars right, two slashes) to extract the variable-length part from the middle.
Result:
Column1 Column2 Column3
AB 1234 10
AB ANYNUMBEROF-CHARACTERS 10
One approach is to use PARSENAME:
SELECT PARSENAME(REPLACE('AB/1234/10','/','.'), 3) Col1,
PARSENAME(REPLACE('AB/1234/10','/','.'), 2) Col2,
PARSENAME(REPLACE('AB/1234/10','/','.'), 1) Col3
This will replace the / with ., and pull out each section of the string with PARSENAME.
The benefit is that it will work with any length of characters in any position. The limits is that PARSENAME only handles up to 4 positions (in this case you are using 3), and will fail if periods . exist in the string already.
Try this. This should work with any number of characters.
DECLARE #str VARCHAR(100) = 'AB/1234/10'
SELECT LEFT(#str, CHARINDEX('/', #str) - 1) AS Column1
, SUBSTRING(#str, CHARINDEX('/', #str) + 1, CHARINDEX('/', SUBSTRING(#str, CHARINDEX('/', #str) + 1, LEN(#str))) - 1) AS Column2
, RIGHT(#str, CHARINDEX('/', REVERSE(#str)) - 1) AS Column3

How to Extract the middle characters from a string without an specific index to start and end it before the space character is read?

I have a column that contains data like:
AB-123 XYZ
ABCD-456 AAA
BCD-789 BBB
ZZZ-963
Y-85
and this is what i need from those string:
123
456
789
963
85
I need the characters from the left after the dash('-') character, then ends before the space character is read.
Thank You guys.
Note: Original tag on this question was Oracle and this answer is based on that tag. Now that, tag is updated to SqlServer, this answer is no longer valid, if somebody looking for Oracle solution, this may help.
Use regular expression to arrive at sub string.
select trim(substr(regexp_substr('ABCD-456 AAA','-[0-9]+ '),2)) from dual
'-[0-9]+ ' will grab any string pattern which starts with dash has one or more digits and ends with a ' ' and returns number with dash
substr will remove '-' from above output
trim will remove any trailing ' '
Check This.
Using Substring and PatIndex.
select
SUBSTRING(colnm, PATINDEX('%[0-9]%',colnm),
PATINDEX('%[^0-9]%',ltrim(RIGHT(colnm,LEN(colnm)-CHARINDEX('-',colnm)))))
from
(
select 'AB-123 XYZ' colnm union
select 'ABCD-456 AAA' union
select 'BCD-789 BBB' union
select 'ZX- 23 BBB'
)a
OutPut :
Try this
http://rextester.com/YTBPQD69134
CREATE TABLE Table1 ([col] varchar(12));
INSERT INTO Table1
([col])
VALUES
('AB-123 XYZ'),
('ABCD-456 AAA'),
('BCD-789 BBB');
select substring
(col,
charindex('-',col,1)+1,
charindex(' ',col,1)-charindex('-',col,1)
) from table1;
Assume all values has '-' and followed by a space ' '. Below solution will not tolerant to exception case:
SELECT
*,
SUBSTRING(Value, StartingIndex, Length) AS Result
FROM
-- You can replace this section of code with your table name
(VALUES
('AB-123 XYZ'),
('ABCD-456 AAA'),
('BCD-789 BBB')
) t(Value)
-- Use APPLY instead of sub-query is for debugging,
-- you can view the actual parameters in the select
CROSS APPLY
(
SELECT
-- Get the first index of character '-'
CHARINDEX('-', Value) + 1 AS StartingIndex,
-- Get the first index of character ' ', then calculate the length
CHARINDEX(' ', Value) - CHARINDEX('-', Value) - 1 AS Length
) b

Use of substring in SQL

My query is the following:
SELECT id, category FROM table1
This returns the following rows:
ID|category
1 |{IN, SP}
2 |
3 |{VO}
Does anyone know how i can remove the first char and last char of the string in PostgreSQL, so it removes: {}?
Not sure, what you mean with "foreign column", but as the column is an array, the best way to deal with that is to use array_to_string()
SELECT id, array_to_string(category, ',') as category
FROM table1;
The curly braces are not part of the stored value. This is just the string representation of an array that is used to display it.
Either using multiple REPLACE functions.
SELECT id, REPLACE(REPLACE(category, '{', ''), '}', '')
FROM table1
Or using a combination of the SUBSTRING, LEFT & LENGTH functions
SELECT id, LEFT(SUBSTRING(category, 2, 999),LENGTH(SUBSTRING(category, 2, 999)) - 1)
FROM table1
Or just SUBSTRING and LENGTH
SELECT id, SUBSTRING(category, 2, LENGTH(category)-2)
FROM table1
You could replace the {} with an empty string
SELECT id, replace(replace(category, '{', ''), '}', '') FROM table1
select id,
substring(category,charindex('{',category,len(category))+2,len(category)-2)
from table1;
select id
,left(right(category,length(category)-1),length(category)-2) category
from boo
select id
,trim(both '{}' from category)
from boo
Trim():
Remove the longest string containing only the characters (a space by
default) from the start/end/both ends of the string
The syntax for the replace function in PostgreSQL is:
replace( string, from_substring, to_substring )
Parameters or Arguments
string
The source string.
from_substring
The substring to find. All occurrences of from_substring found within string are replaced with to_substring.
to_substring
The replacement substring. All occurrences of from_substring found within string are replaced with to_substring.
UPDATE dbo.table1
SET category = REPLACE(category, '{', '')
WHERE ID <=3
UPDATE dbo.table1
SET category = REPLACE(category, '}', '')
WHERE ID <=3

SQL Server 2012 Removing part of string before and after specific, repeating character

Would you please assist with a perplexing string operator problem?
I need to parse a NVARCHAR(32), not null column called MachineName from table dbo.Log. The format is either:
AA-BBB-CCC-DDD
AA-BBB-CCCC-DDD
AA-BBB-CCC-DDDD
AA-BBB-CCCC-DDDD
I need the Result Set (as [Code]) to be either CCC or CCCC.
I consulted this article:
http://basitaalishan.com/2014/02/23/removing-part-of-string-before-and-after-specific-character-using-transact-sql-string-functions/
With this code:
SELECT DISTINCT [MachineName]
,REPLACE(SUBSTRING([MachineName], CHARINDEX('-', [MachineName],6), LEN([MachineName])), '-', '') AS [Code]
FROM [dbo].[Log]
My current Result Set is fine on the left, but the right needs refinement.
CCCDDD
CCCCDDDD
I would defintely appreciate your help! Thank you in advance
You can improvise on this: http://sqlfiddle.com/#!3/9eecb7d/588
with test as (
select cast('AA-BBB-CCC-DDD' as nvarchar(32)) as field1
union all
select cast('AA-BBB-CCCC-DDD' as nvarchar(32)) as field1
union all
select cast('AA-BBB-CCC-DDDD' as nvarchar(32)) as field1
union all
select cast('AA-BBB-CCCC-DDDD' as nvarchar(32)) as field1
)
select
substring(
substring(field1,8,32),
1,
charindex('-', substring(field1,8,32))-1
)
from test
Result:
CCC
CCCC
CCC
CCCC
With substring, we ignore the first 7 characters and start with 8th character. That'll give us CCCC-DDD and such. charindex will tell us the position of - in CCCC-DDD and such. We reapply substring on the substring; starting with first position and capturing all up until - was found.
In your case, you could do:
select distinct
substring(
substring(MachineName,8,32),
1,
charindex('-', substring(MachineName,8,32))-1
) as Code
from dbo.Log

Update one column from substring of another column

I have an existing column that I would like to take a subset of and insert into a second (new) column in the same table.
e.g. MyTable.[FullName] (existing column) contains a string like "P-13-146 PS - Goodyear - Tire repair"
I created a new column, MyTable.[ShortName] that I want to insert a substring of the value from the first column into ("P-13-146 PS"). The problem is that the length of the substring is different for each full name. The only real consistency is that I want up to the second whitespace character.
I am trying to resolve the following:
UPDATE [MyTable] SET [ShortName] = ???
Try this:
declare #exp varchar(200)
set #exp='P-13-146 PS - Goodyear - Tire repair'
select RTRIM(SUBSTRING(#exp,1,CHARINDEX(' ',#exp,charindex(' ',#exp)+1)))
Just combine the string manipulation functions until you get what you want:
SELECT
CASE WHEN CHARINDEX(' ',FullName, CHARINDEX(' ', FullName)+1) = 0 THEN FullName
ELSE SUBSTRING(FullName, 1, CHARINDEX(' ',FullName, CHARINDEX(' ', FullName)+1)-1)
END ShortName
FROM MyTable
The first part of the CASE statement is for names that have fewer than two spaces.