sql trimming function - sql

I have a table called transactions which has a column Customer_Transactions_ID
Now the values in this column vary in the below
AB_EL_205_72330_H
AB_EL_820_23066_E_N
AB_EL_820_23066
I want to trim all the values that start with "AB_EL" to make them from
AB_EL_820_23066_E_N (or whatever variation of the above) to
AB_EL_820_23066
So basically no E or H after the id's
Is this possible?

This will give your values truncated until the last ocurrence of a number.
SELECT
Original = T.Customer_Transactions_ID,
Truncated = SUBSTRING(
T.Customer_Transactions_ID,
1,
LEN(T.Customer_Transactions_ID) - PATINDEX('%[0-9]%', REVERSE(T.Customer_Transactions_ID)) + 1)
FROM
Transactions AS T

if i understand your requirement correctly.if text starts with ab_el then trim _e,_l from the text.
DECLARE #txt VARCHAR(100)= 'aqb_el_205_72330_h';
SELECT ISNULL('ab_el'+CASE
WHEN #txt LIKE 'ab_el%'
THEN replace(replace(REPLACE(#txt,'ab_el',''), '_e', ''), '_h', '')
END,#txt);

Related

Extract Value between two specific varchar

I want to extract numeric value from a varchar in SQL Server 2014
XXXX 0.5Kg I want to return 0.5
XXX 25YY 1.25Kg I want to return 1.25
I want the number between last space from left and Kg
Thanks
You could do
select replace(right(str, charindex(' ',reverse(str))),'Kg','')
from your_table;
DECLARE #string as VARCHAR(MAX) = 'XXX 25YY 1.25Kg'
DECLARE #string_ as VARCHAR(MAX) = 'XXXX 0.5Kg'
SELECT REPLACE(RIGHT(#string, CHARINDEX(' ',REVERSE(#string))),'Kg','')
SELECT REPLACE(RIGHT(#string_, CHARINDEX(' ',REVERSE(#string_))),'Kg','')
First find out the first space in the reverse order of the string and then break the string from that space. the replace the 'kg' from '' to obtain the value that you need. Test the result with many strings. You can use RIGHT string function in SQL to get the specific part from the string.

Concatenate Strings with Spaces into a varchar(255) column

I am writing an ETL logic to insert four source columns at a certain position of a certain length into a target varchar(255) column. I have tried several ways but unable to find a solution for it. Any help is much appreciated.
Ex:
Source:
Column_id at Column 14, len 8
+
name at Column 43, len 27
+
term at Column 133, len 1
Target:
Description varchar(255)
You could convert the data to char like this:
select REPLICATE(' ', 14)+convert(char(8), column_id)+REPLICATE(' ', 43-8-14) + convert(char(27), name) + REPLICATE(' ', 133-43-27)+convert(char(1), term)
from <whatever table not provided>
I left '133-43-27' as a example, test it so it's the right position...
You can try something along this:
a declared table to simulate your issue
DECLARE #tbl TABLE(id INT IDENTITY, [name] VARCHAR(100), term VARCHAR(100));
INSERT INTO #tbl VALUES('Name One','first term')
,('One more name','One more term');
-- some variables for a generic approach
DECLARE #posId INT=1
,#posName INT=10
,#posTerm INT=50;
--the query
SELECT t.*
,STUFF(
STUFF(
STUFF(trg,#posId, LEN(t.id), t.id)
,#posName, LEN(t.[name]), t.[name])
,#posTerm, LEN(t.term), t.term)
FROM #tbl t
CROSS APPLY(SELECT REPLICATE(' ',255)) A(trg)
--the result
1 Name One first term
2 One more name One more term
The idea in short:
First we use CROSS APPLY(SELECT ...) to add a column to our result set. This column is a string, created off 255 blanks.
Now we can use STUFF(). This functions stuffs given characters into an existing string. By replacing the exact count of characters we will not touch the total length.
Hint 1: If your data might have trailing blanks LEN() can trick you out. You can either use TRIM() (older versions LTRIM() and RTRIM()) or DATALENGTH() (be aware of 2 bytes with NVARCHAR!) then...
Hint 2: If you have to cut your data to a max length, you can use LEFT()
STUFF() does what you want. But you want to be really careful about overwriting all the data that is there. For that, I would suggest casting to a char() type:
SELECT t.*,
STUFF(STUFF(STUFF(target, 14, 8, CONVERT(CHAR(8), t.id
), 43, 27, CONVERT(CHAR(27), t.name
), 133, 1, CONVERT(CHAR(1), t.term
)
FROM t;
The CHAR() type pads the values with spaces, which means that this code will overwrite any existing data in those positions (and only in those positions).

need to replace some underscores with hypens

I have a column with value
AAA_ZZZZ_7890_10_28_2014_123456.jpg
I need to replace the middle underscores so that it displays it as date i.e.
AAA_ZZZZ_7890_10-28-2014_123456.jpg
Can some one please suggest a simple update query for this.
The Number of Underscores would be same for all the values in the column but the length will vary for example some can have
AAA_q10WRQ_001_10_28_2014_12.jpg
The following should do it:
http://sqlfiddle.com/#!3/d41d8/30384/0
declare #filename varchar(64) = 'AAA_ZZZZ_7890_10_28_2014_123456.jpg'
declare #datepattern varchar(64) = '%[_][0-1][0-9][_][0-3][0-9][_][1-2][0-9][0-9][0-9][_]%'
select
filename,
substring(filename,1,datepos+2)+'-'+
substring(filename,datepos+4,2)+'-'+
substring(filename,datepos+7,1000)
from
(
select
#filename filename,
patindex(#datepattern,#filename)
as datepos
) t
;
Resulting in
AAA_ZZZZ_7890_10-28-2014_123456.jpg
Caveats to watch out for:
It is important to exactly define how you find the date. In my definition it is MM_DD_YYYY surrounded by further two underscores, and I check that the first digits of M,D,Y are 0-1,0-3,1-2 respectively (i.e. I do NOT check if month is e.g. 13.) -- of course we assume that there is only one such string in any file name.
datepos actually finds the position of the underscore before the date -- this is not an issue if taken into account in the indexing of substring.
in the 3rd substring the length cannot be NULL or infinity and I couldn't get LEN() to work in SQL Fiddle so I dirty hardcoded a large enough number (1000). Corrections to this are welcome.
Try this (assuming that the DATE portion always starts at the same character index)
declare #string varchar(64) = 'AAA_ZZZZ_7890_10_28_2014_123456.jpg'
select replace(#string, reverse(substring(reverse(#string), charindex('_', reverse(#string), 0) + 1, 10)), replace(reverse(substring(reverse(#string), charindex('_', reverse(#string), 0) + 1, 10)), '_', '-'))
If there are exactly 6 _ then for the first
select STUFF ( 'AAA_ZZZZ_7890_10_28_2014_123456.jpg' , CHARINDEX ( '_' ,'AAA_ZZZZ_7890_10_28_2014_123456.jpg', CHARINDEX ( '_' ,'AAA_ZZZZ_7890_10_28_2014_123456.jpg', CHARINDEX ( '_' ,'AAA_ZZZZ_7890_10_28_2014_123456.jpg', CHARINDEX ( '_' ,'AAA_ZZZZ_7890_10_28_2014_123456.jpg', 0 ) + 1 ) + 1 ) + 1 ) , 1 , '-' )

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.

TSQL How to get the 2nd number from a string

We have the below in row in MS SQL:
Got event with: 123.123.123.123, event 34, brown fox
How can we extract the 2nd number ie the 34 reliable in one line of SQL?
Here's one way to do it using SUBSTRING and PATINDEX -- I used a CTE just so it wouldn't look so awful :)
WITH CTE AS (
SELECT
SUBSTRING(Data,CHARINDEX(',',Data)+1,LEN(Data)) data
FROM Test
)
SELECT LEFT(SUBSTRING(Data, PATINDEX('%[0-9]%', Data), 8000),
PATINDEX('%[^0-9]%',
SUBSTRING(Data, PATINDEX('%[0-9]%', Data), 8000) + 'X')-1)
FROM CTE
And here is some sample Fiddle.
As commented, CTEs will only work with 2005 and higher. If by chance you're using 2000, then this will work without the CTE:
SELECT LEFT(SUBSTRING(SUBSTRING(Data,CHARINDEX(',',Data)+1,LEN(Data)),
PATINDEX('%[0-9]%', SUBSTRING(Data,CHARINDEX(',',Data)+1,LEN(Data))), 8000),
PATINDEX('%[^0-9]%',
SUBSTRING(SUBSTRING(Data,CHARINDEX(',',Data)+1,LEN(Data)),
PATINDEX('%[0-9]%', SUBSTRING(Data,CHARINDEX(',',Data)+1,LEN(Data))), 8000) + 'X')-1)
FROM Test
Simply replace #s with your column name to apply this to a table. Assuming that number is between last comma and space before the last comma. Sql-Fiddle-Demo
declare #s varchar(100) = '123.123.123.123, event 34, brown fox'
select right(first, charindex(' ', reverse(first),1) ) final
from (
select left(#s,len(#s) - charindex(',',reverse(#s),1)) first
--from tableName
) X
OR if it is between first and second commas then try, DEMO
select substring(first, charindex(' ',first,1),
charindex(',', first,1)-charindex(' ',first,1)) final
from (
select right(#s,len(#s) - charindex(',',#s,1)-1) first
) X
I've thought of another way that's not been mentioned yet. Presuming the following are true:
Always one comma before the second "part"
It's always the word "event" with the number in the second part
You are using SQL Server 2005+
Then you could use the built in ParseName function meant for parsing the SysName datatype.
--Variable to hold your example
DECLARE #test NVARCHAR(50)
SET #test = 'Got event with: 123.123.123.123, event 34, brown fox'
SELECT Ltrim(Rtrim(Replace(Parsename(Replace(Replace(#test, '.', ''), ',', '.'), 2), 'event', '')))
Results:
34
ParseName parses around dots, but we want it to parse around commas. Here's the logic of what I've done:
Remove all existing dots in the string, in this case swap them with empty string.
Swap all commas for dots for ParseName to use
Use ParseName and ask for the second "piece". In your example this gives us the value
" event 34".
Remove the word "event" from the string.
Trim both ends and return the value.
I've no comments on performance vs. the other solutions, and it looks just as messy. Thought I'd throw the idea out there anyway!