Get Substrings From DB2 Column - db2

I Have: AAAA/DATA1/Data2;xyx;pqr
this data
I want only:DATA1 And Data2

If this is for a specific row, maybe use SUBSTR? Something like
SELECT
SUBSTR(column, 6, 5) AS col1
, SUBSTR(column, 13, 5) AS col2
FROM table
Here is something else you can do.. Although it gets pretty complicated, and this isn't the exact answer you are looking for but it will get you started. Hope this helps:
WITH test AS (
SELECT characters
FROM ( VALUES
( 'AAAA/DATA1/Data2;xyx;pqr'
) )
AS testing(characters)
)
SELECT
SUBSTR(characters, 1, LOCATE('/', characters) - 1) AS FIRST_PART
, SUBSTR(characters, LOCATE('/', characters) + 1) AS SECOND_PART
, SUBSTR(characters, LOCATE('/', characters, LOCATE('/', characters) + 1) + 1)
AS THIRD_PART
FROM test
;
DB2 does not have a single function for this, unfortunately. Check out this answer here: How to split a string value based on a delimiter in DB2

Related

Trying to extract text using CHARINDEX ()- 1 but getting an error

I have a column with Names, and I am trying to split the column into First and Last Name using Text functions such as LEFT/SUBSTRING/CHARINDEX.
Data in the column:
Name
Yang, Jon
Huang, Eugene
Torres, Ruben
Zhu, Christy
Johnson, Elizabeth
Everything works fine as long as I use this code:
SELECT
[Name]
--,LEFT([Name], CHARINDEX(' ', [Name])) AS FirstName
,SUBSTRING([Name], 1, CHARINDEX(' ', [Name] )) AS FirstName
FROM
DataModeling.Customer
But the problem arises when I try to subtract 1 from CHARINDEX to exclude the Comma from the result and it throws this error:
I have done this operation many times in Excel so trying to replicate it with TSQL. Any suggestion on what I am doing wrong is helpful.
You get that error when CHARINDEX(' ', [Name] ) return 0. So minus 1 will make it negative and it is invalid value for substring()
You can use CASE expression to check the return value from CHARINDEX() and return the correct value to substring()
Or, you can "cheat" by using
CHARINDEX( ' ', [Name] + ' ' )
So CHARINDEX() will always return a value that is more than 0

TSQL query to extract a value between to char where a specific set of characters is there

I have a problem I can't seem to figure out. I am trying to extract capacity from a product description. It is always between two values, "," and "oz." however there could be other commas included in the description that are not part of what I'm trying to extract. Example value is , 15 oz., or , 2 oz.,
I'm trying to find values that have the oz in them and are between two commas and I have been completely unsuccessfully. I've tried many things, but here is the latest that I have tried today and I'm just getting an error.
SELECT SUBSTRING(
FullDescription,
CHARINDEX(',', FullDescription),
CHARINDEX('oz.',FullDescription)
- CHARINDEX(',', FullDescription)
+ Len('oz.')
)
from CatalogManagement.Product
Since the backwards pattern ,.zo is more recognisable, I'd go with the REVERSE function
Sample values:
"something, something more, 18oz., complete"
"shorter, 12oz., remainder"
"there is no capacity, in this, value"
"a bit more, 14oz, and some followups, maybe"
SELECT REVERSE(
SUBSTRING (
REVERSE(FullDescription),
CHARINDEX(',.zo', REVERSE(FullDescription)) + 1,
CHARINDEX(',', REVERSE(FullDescription), CHARINDEX(',.zo', REVERSE(FullDescription)) + 1) - CHARINDEX(',.zo', REVERSE(FullDescription)) - 1
)
)
FROM CatalogManagement.Product
WHERE FullDescription LIKE '%oz.,%'
You might use XML-splitting together with a XQuery predicate:
DECLARE #tbl TABLE(ID INT IDENTITY, YourString VARCHAR(MAX));
INSERT INTO #tbl VALUES('Here is one with an amount, 1 oz., some more text')
,('Here is one with no amount, some more text')
,('a, 10 oz.')
,('b, 20oz., no blank between oz and the number')
,('30oz., starts with the pattern, no leading comma');
SELECT t.*
,A.oz.value('.','nvarchar(max)') oz
FROM #tbl t
CROSS APPLY(SELECT CAST('<x>' + REPLACE((SELECT t.YourString AS [*] FOR XML PATH('')),',','</x><x>') + '</x>' AS XML)
.query('/x[contains(text()[1],"oz.")]')) A(oz);
The idea in short:
We use some string methods to replace commas with XML tags and to cast your string to XML. each fragment is placed within a decent <x> element.
We use a predicate to return just the fragments containing "oz.".
You can filter easily with
WHERE LEN(A.oz.value('.','nvarchar(max)'))>0

How to find/replace weird whitespace in string

I find in my sql database string whit weird whitespace which cannot be replace like REPLACE(string, ' ', '') RTRIM and cant it even find with string = '% %'. This space is even transfered to new table when using SELECT string INTO
If i select this string in managment studio and copy that is seems is normal space and when everything is works but cant do nothing directly from database. What else can i do? Its some kind of error or can i try some special character for this?
First, you must identify the character.
You can do that by using a tally table (or a cte) and the Unicode function:
The following script will return a table with two columns: one contains a char and the other it's unicode value:
DECLARE #Str nvarchar(100) = N'This is a string containing 1 number and some words.';
with Tally(n) as
(
SELECT TOP(LEN(#str)) ROW_NUMBER() OVER(ORDER BY ##SPID)
FROM sys.objects a
--CROSS JOIN sys.objects b -- (unremark if there are not enough rows in the tally cte)
)
SELECT SUBSTRING(#str, n, 1) As TheChar,
UNICODE(SUBSTRING(#str, n, 1)) As TheCode
FROM Tally
WHERE n <= LEN(#str)
You can also add a condition to the where clause to only include "special" chars:
AND SUBSTRING(#str, n, 1) NOT LIKE '[a-zA-Z0-9]'
Then you can replace it using it's unicode value using nchar (I've used 32 in this example since it's unicode "regular" space:
SELECT REPLACE(#str, NCHAR(32), '|')
Result:
This|is|a|string|containing|1|number|and|some|words.

trimming using substr and instr function

I have a table customer. Contains cus_info as 'ceg_cus_hongkong_21032015_HHMISS'.
I need only the country name from the following mentioned string that is hongkong. And this will be generic for all data provided in cus_info column.
Please help me out how can it be possible using substr?
select
substr(cus_info,
instr(cus_info ,'_', 1, 2),
(
instr(cus_info ,'_', 1, 3) -- position of 3rd _
-
instr('cus_info ,'_', 1, 2) -- position of 2nd _
)
)
from customer

T-SQL: How to obtain the exact length of a string in characters?

I'm generating T-SQL SELECT statements for tables for which I have no data type information up-front. In these statements, I need to perform string manipulation operations that depend on the length of the original value of the tables' columns.
One example (but not the only one) is to insert some text at a specific position in a string, including the option to insert it at the end:
SELECT
CASE WHEN (LEN ([t0].[Product] = 8)
THEN [t0].[Product] + 'test'
ELSE STUFF ([t0].[Product], 8, 0, 'test')
END
FROM [OrderItem] [t0]
(The CASE WHEN + LEN is required because STUFF doesn't allow me to insert text at the end of a string.)
The problem is that LEN excludes trailing blanks, which will ruin the calculation.
I know I can use DATALENGTH, which does not exclude trailing blanks, but I can't convert the bytes returned by DATALENGTH to the characters required by STUFF because I don't know whether the Product column is of type varchar or nvarchar.
So, how can I generate a SQL statement that depends on the exact length of a string in characters without up-front information about the string data type being used?
Here's what I ended up using:
SELECT
CASE WHEN ((LEN ([t0].[Product] + '#') - 1) = 8)
THEN [t0].[Product] + 'test'
ELSE STUFF ([t0].[Product], 8, 0, 'test')
END
FROM [OrderItem] [t0]
Measurements indicate that the LEN (... + '#') - 1 trick is about the same speed as LEN (...) alone.
Thanks for all the good answers!
try this:
SELECT
CASE WHEN (LEN (REPLACE([t0].[Product],' ', '#') = 8)
THEN [t0].[Product] + 'test'
ELSE STUFF ([t0].[Product], 8, 0, 'test')
END
FROM [OrderItem] [t0]
Can't you look up the type information for the columns in the system tables?
If not then to determine whether or not a column is varchar or nvarchar this would do it.
create table #test
(
c varchar(50),
n nvarchar(50)
)
insert into #test values ('1,2,3,4 ',N'1,2,3,4,5 ')
SELECT
CASE
WHEN datalength(CAST(c AS nvarchar(MAX))) = datalength(c)
THEN 'c is nvarchar'
ELSE 'c is char'
END,
CASE
WHEN datalength(CAST(n AS nvarchar(MAX))) = datalength(n)
THEN 'n is nvarchar'
ELSE 'n is char'
END
FROM #test
Use DATALENGTH and SQL_VARIANT_PROPERTY:
SELECT
CASE
WHEN 8
= DATALENGTH([t0].[Product])
/ CASE SQL_VARIANT_PROPERTY([t0].[Product],'BaseType') WHEN 'nvarchar' THEN 2 ELSE 1 END
THEN [t0].[Product] + 'test'
ELSE STUFF ([t0].[Product], 8, 0, 'test')
END
FROM [OrderItem] [t0]
If there are no leading blanks, len(reverse(column_name)) will give you the column length.