split string with character - sql

using SQL 2008; I have the following string:
EMCo: 1 WorkOrder: 12770 WOItem: 10
I am trying to get the WorkOrder #.
When the string did not have the WOItem on end of it, I was able to use the following statement to get WorkOrder #.
[WorkOrder] = LTRIM(RTRIM(RIGHT(HQMA.KeyString,CHARINDEX(':',REVERSE(HQMA.KeyString))-1)))
This statement moves and may have double digits for the Co#, and it does not always have WOItem #. Was hoping to find something that would split after the ":" and just take 2nd group.
Any suggestions?

The patindex suggestion above will work beautifully, now if you still want to use your current statement, substring will pull the same values, and replace will take out WOItem. Not very elegant, it works whether you have WOItem or not:
select substring(LTRIM(RTRIM(RIGHT(REPLACE(HQMA.KeyString,'WOItem:',''),
CHARINDEX(':',REVERSE(REPLACE(HQMA.KeyString,'WOItem:','')))-1))),0,7)
select substring(LTRIM(RTRIM(RIGHT(REPLACE(HQMA.KeyString,'WOItem:',''),
CHARINDEX(':',REVERSE(REPLACE(HQMA.KeyString,'WOItem:','')))-1))),0,7)

How about using patindex()? Assuming the work order always has five characters:
select substring(HQMA.KeyString,
patindex('%WorkOrder: %', HQMA.KeyString) + 11,
5) as WorkOrder

Related

Trim a character on SQL

Hi everyone this is my first time that i asked something.
I have multiple codes on my db with numbers and '/', for example:
510325205
510325205/000/01
510565025-01
510565025-01/090/03
...
I need to trim the / - I need these results:
510325205
510325205
510565025-01
510565025-01
...
I already searched and tried this
left(code, charindex('/', code))
and it works for the codes with / in it, but the codes without / are excluded from the results.
Thanks for your help!
Your try was very close.
All you needed to add was -1.
As you can see the explanation for the left() function:
The LEFT() function extracts a number of characters from a string
(starting from left): LEFT(string, number_of_chars)
With charindex() function you have told the left() function how many characters to take. By adding -1 to that you have removed the '/' sign because you have told the LEFT() function to take 10 characters and not 11(for example) because 11th character is '/'.
select left('510325205/000/01',charindex('/','510325205/000/01')-1)
or because you have column named code
select left(code,charindex('/',code)-1)
If you have values without / you can use this:
select case when charindex('/',code_c)-1 = -1
then
code_c
else
left(code_c,charindex('/',code_c)-1)
end RESULT
from test
OR
select left(code_c,iif(charindex('/',code_c)-1 = -1, len(code_c), charindex('/',code_c)-1))
from test
Here is DEMO

How to trim a string which changes at each result

I have data which contains a date and a batch number. I need to be able to trim down the batch number removing the leading word "Job " from each. The issue i have is each result is different and is of a different length also.
To try and deal with this i have tried to use LEFT and CHARINDEX to trim it but get a syntax error back. Because i am using MS Query on a open edge v10 progress odbc database it is not clear as to what the issue is. Below is the code i have produced.
SELECT
Delivery_0.DelProposedDate
, Delivery_0.DelBatchNumber
, LEFT(Delivery_0.DelBatchNumber,CHARINDEX(' ',Delivery_0.DelBatchNumber)-1) as 'JobID'
FROM SBS.PUB.Delivery Delivery_0
Currently the data looks like this:
DelProposedDate DelBatchNumber
05/05/2017 Job 321924
08/02/2019 Job 356812/4
29/03/2017 Job 328585
I am trying to get it to look like this:
DelProposedDate DelBatchNumber JobID
05/05/2017 Job 321924 321924
08/02/2019 Job 356812/4 356812/4
29/03/2017 Job 328585 328585
You want to exclude the left-most 4 characters ('Job '). This is the same a showing the right-most x characters where x = length-of-string - 4. I'm not that conversant with Progress' variant of SQL, but something like:
Right(DelBatchNumber, Len(DelBatchNumber) - 4)
would do it. You may need to substitute the Progress equivalent of Right and Len, and possibly check the order of the parameters Right takes.
SQL Server has a function that explicitly does this, STUFF():
select stuff(Delivery_0.DelBatchNumber, 1, 4, '')
This replaces the first four characters with an empty string.
try
select replace ('Job 321924','Job ','')
output
'321924'
first parameter is the string you want to change,
second parameter is the string you want to replace,
third parameter is the string you want to replace with.
So here i simply replaced 'Job ' by an empty string
Note that it returns a string and not an integer, you might need to use CONVERT/CAST if you want the result as integer
You can try this, which tries to replace the 'Job ' string with empty string:
SELECT
Delivery_0.DelProposedDate
, Delivery_0.DelBatchNumber
, REPLACE(Delivery_0.DelBatchNumber,'Job ','') as 'JobID'
FROM SBS.PUB.Delivery Delivery_0

What does the trim function mean in this context?

Database I'm using: https://uploadfiles.io/72wph
select acnum, field.fieldnum, title, descrip
from field, interest
where field.fieldnum=interest.fieldnum and trim(ID) like 'B.1._';
What will the output be from the above query?
Does trim(ID) like 'B.1._' mean that it will only select items from B.1._ column?
trim removes spaces at the beginning and end.
"_" would allow representing any character. Hence query select any row that starts with "B.1."
For eg.
'B.1.0'
'B.1.9'
'B.1.A'
'B.1.Z'
etc
Optional Wildcard characters allowed in like are % (percent) and _ (underscore).
A % matches any string with zero or more characters.
An _ matches any single character.
I don't know about the DB you are using but trim usually remove spaces around the argument you give to it.
The ID is trimmed to be sure to compare the ID without any white-space around it.
About your second question, Only the ROWS with an ID like 'B.1.' will be selected.
SQL like
SQL WHERE

Comparing fields when a field has data in between 2 characters that match the field being compared

I have code that looks like this:
left outer join
gme_batch_header bh
on
substr(ln.lot_number,instr(ln.lot_number,'(') + 1,
instr(ln.lot_number,')') - instr(ln.lot_number,'(') - 1)
=
bh.batch_no
It works fine, but I have come across a few lot numbers that have two sections of strings that are between parenthesis. How would I compare what is between the second set of parenthesis? Here is an example of the data in the lot number field:
E142059-307-SCRAP-(74055)
This one works with the code,
58LF-3-B-2-2-2 (SCRAP)-(61448)
This one tries comparing SCRAP with the batch no, which isn't correct. It needs to be the 61448.
The result is always the last item in parenthesis.
After more research, I actually got it to work with this code:
substr(ln.lot_number,instr(ln.lot_number,'(',-1) + 1, instr(ln.lot_number,')',-1) - instr(ln.lot_number,'(',-1) - 1)
Assuming SQL2005+, and it is always the last occurrence you want, then I would suggest finding the last instance of a ( in your query and substring to there. To get the last instance you could use something like:
REVERSE(SUBSTRING(REVERSE(lot_number),0,CHARINDEX('(',REVERSE(lot_number))))
If your version of Oracle supports regular expressions try this:
substr(regexp_substr(ln.lot_number,'[0-9]+\)$'),1,length(regexp_substr(ln.lot_number,'[0-9]+\)$'))-1)
Explanation:
regexp_substr(scrap_row,'[0-9]+\)$' ==> find me just numbers in the string that ends in ). This returns the numbers but it includes the closing parenthesis.
To remove the closing parenthsis, just send it through substring and extract first number through the length of the number stopping at 1 character from the end of the string.
Query for analysis:
with scrap
as (select '58LF-3-B-2-2-2 (SCRAP)-(61448)' as scrap_row from dual)
select scrap_row,
regexp_substr(scrap_row,'[0-9]+\)$') as regex_substring,
length(regexp_substr(scrap_row,'[0-9]+\)$')) as length_regex_substring,
substr(regexp_substr(scrap_row,'[0-9]+\)$'),1,length(regexp_substr(scrap_row,'[0-9]+\)$'))-1) as regex_sans_parenthesis
from scrap
If you have 11g, this will do it pretty simply by using the subgroup argument of regexp_substr() and constructing the regex appropriately:
SQL> with tbl(data) as
(
select 'E142059-307-SCRAP-(74055)' from dual
union
select '58LF-3-B-2-2-2 (SCRAP)-(61448)' from dual
)
select data from tbl
where regexp_substr(data, '\((\d+)\)$', 1, 1, NULL, 1)
= '61448';
DATA
------------------------------
58LF-3-B-2-2-2 (SCRAP)-(61448)
The regular expression can be read as:
\( - Search for a literal left paren
( - Start a remembered subgroup
\d+ - followed by 1 more more digits
) - End remembered subgroup
\) - followed by a literal right paren
$ - at the end of the line.
The regexp_substr function arguments are:
Source - the source string
Pattern - The regex pattern to look for
position - Position in the string to start looking for the pattern
occurrence - If the pattern occurs multiple times, which occurrence you want
match_params - See the docs, not used here
subexpression - which subexpression to use (the remembered group)
So in English, look for a series of 1 or more digits surrounded by parens, where it occurs at the end of the line and save the digit part only to use to compare. IMHO a lot easier to follow/maintain than nested instr(), substr().
For re-useability, make a function called get_last_number_in_parens() that contains this code and uses an argument of the string to search. This way that logic is encapsulated and can be re-used by folks that may not be so comfortable with regular expressions, but can benefit from the power! One place to maintain code too. Then call like this:
select data from tbl
where get_last_number_in_parens(data) = '61448';
How easy is that?!
Hello you can check with this code. It works whaever the condition may be
SELECT SUBSTR('58LF-3-B-2-2-2-(61448)',instr('58LF-3-B-2-2-2-(61448)','(',-1)+1,LENGTH('58LF-3-B-2-2-2-(61448)')-instr('58LF-3-B-2-2-2-(61448)','(',-1)-1)
FROM dual;
SELECT SUBSTR('58LF-3-B-2-2-2 (SCRAP)-(61448)',instr('58LF-3-B-2-2-2 (SCRAP)-(61448)','(',-1)+1,LENGTH('58LF-3-B-2-2-2 (SCRAP)-(61448)')-instr('58LF-3-B-2-2-2 (SCRAP)-(61448)','(',-1)-1)
FROM dual;
Output
==================================
61448
==================================

How to return the second to last character in a string using SQL

I am trying to only return the second to last character from a string using MS SQL.
I've tried using MID and Substring but the length of the string isn't always the same for the column I am trying to return, So I can't do it that way.
So say I am returning the codes of something:
Code
'1234'
I want to just return '3' from that code.
How can I do this?
Cheers in advance :)
Use SUBSTRING and LEN. LEN gives you the length of the string, then subtract 1 to get the previous char:
SELECT SUBSTRING(Code, LEN(Code)-1,1)
How about
select left(right(code, 2), 1) from MyTable;
You might need to validate that the string actually has at least 2 chars, however.
SqlFiddle here