I have a string of comma separated values, I am loading these values into a system that has a max length I need to abide by. Once the string hits a max length it should move the values to another column but retain values. For the sake of this example below, I only need to split the string into two columns.
For example my string value = val1,val2,val3,val4,val5
Max length of output fields = 15
Output should be two columns:
ValueList1 ValueList2
val1,val2,val3 val4,val5
I'm trying to complete this with T-SQL but this is not a common issue I need to solve and am stumped. Any help would be greatly appreciated.
you can try this.
DECLARE #stringvalue VARCHAR(5000) = 'val1,val2,val3,val4,val5'
DECLARE #MaxLengthofOutputFields INT = 15
SELECT
CASE WHEN LEN(#stringvalue) > #MaxLengthofOutputFields
THEN LEFT(#stringvalue, #MaxLengthofOutputFields - CHARINDEX(',',REVERSE(LEFT(#stringvalue,#MaxLengthofOutputFields))))
ELSE #stringvalue END ,
CASE WHEN LEN(#stringvalue) > #MaxLengthofOutputFields THEN
SUBSTRING(#stringvalue, #MaxLengthofOutputFields - CHARINDEX(',',REVERSE(LEFT(#stringvalue,#MaxLengthofOutputFields))) + 2, LEN(#stringvalue))
END
Result:
-------------------- -------------
val1,val2,val3 val4,val5
Related
I am trying to get last numeric part in the given string.
For Example, below are the given strings and the result should be last numeric part only
SB124197 --> 124197
287276ACBX92 --> 92
R009321743-16 --> 16
How to achieve this functionality. Please help.
Try this:
select right(#str, patindex('%[^0-9]%',reverse(#str)) - 1)
Explanation:
Using PATINDEX with '%[^0-9]%' as a search pattern you get the starting position of the first occurrence of a character that is not a number.
Using REVERSE you get the position of the first non numeric character starting from the back of the string.
Edit:
To handle the case of strings not containing non numeric characters you can use:
select case
when patindex(#str, '%[^0-9]%') = 0 then #str
else right(#str, patindex('%[^0-9]%',reverse(#str)) - 1)
end
If your data always contains at least one non-numeric character then you can use the first query, otherwise use the second one.
Actual query:
So, if your table is something like this:
mycol
--------------
SB124197
287276ACBX92
R009321743-16
123456
then you can use the following query (works in SQL Server 2012+):
select iif(x.i = 0, mycol, right(mycol, x.i - 1))
from mytable
cross apply (select patindex('%[^0-9]%', reverse(mycol) )) as x(i)
Output:
mynum
------
124197
92
16
123456
Demo here
Here is one way using Patindex
SELECT RIGHT(strg, COALESCE(NULLIF(Patindex('%[^0-9]%', Reverse(strg)), 0) - 1, Len(strg)))
FROM (VALUES ('SB124197'),
('287276ACBX92'),
('R009321743-16')) tc (strg)
After reversing the string, we are finding the position of first non numeric character and extracting the data from that position till the end..
Result :
-----
124197
92
16
In SQL server, I have VARCHAR values.
I need a view that automatically reformats data.
Data that is stored in the following form:
hawthorn104freddy#hawthorn.com
scotland2samantha#gmail.com3
birmingham76roger#outlook.co.uk1905student
Needs to be reformatted into the following:
hawthorn 104freddy#hawthorn.com0000
scotland 002samantha#gmail.com 0003
birmingham076roger#outlook.co.uk1905student
Reformatting
Numeric values within the strings are padded with zeros to the length of the longest number
All other characters are padded with space characters to line up the numbers.
Does anyone know how this is done?
Note: Bear in mind that a string may contain any combination of words and numbers.
You should split your values to 4 columns (to find maximum length in each column), then add leading/trailing zeros/spaces, then concat it.
Here is code to split values, hope you will have no problems with adding zeros and spaces:
declare #v varchar(255) = 'hawthorg104freddy#hawthorn.com50'
select
FirstPart = left(#v, patindex('%[a-z][0-9]%', #v)),
SecondPart = substring(#v, patindex('%[0-9]%', #v), patindex('%[0-9][a-z]%', #v) - patindex('%[a-z][0-9]%', #v)),
ThirdPart = substring(#v, patindex('%[0-9][a-z]%', #v) + 1, len(#v) - patindex('%[0-9][a-z]%', #v) - patindex('%[0-9][a-z]%', reverse(#v))),
Fourthpart = right(#v, patindex('%[0-9][a-z]%', reverse(#v)))
Notes:
patindex('%[a-z][0-9]%', #v) - Last letter in hawthorn (nickname?)
patindex('%[0-9][a-z]%', #v) - Last digit in first number (104)
patindex('%[0-9][a-z]%', reverse(#v)) - Length of the last number
You can also use CLR and RegEx to split values to groups:
https://github.com/zzzprojects/Eval-SQL.NET/wiki/SQL-Server-Regex-%7C-Use-regular-expression-to-search,-replace-and-split-text-in-SQL
You can use PATINDEX
declare #str varchar(100)='hawthorn104freddy#hawthorn.com'
SELECT SUBSTRING(#str,0,PATINDEX('%[0-9]%',#str)),
SUBSTRING(#str,PATINDEX('%[0-9]%',#str),LEN(#str)-LEN(SUBSTRING(#str,0,PATINDEX('%[0-9]%',#str))))
My column Details would return a big message such as and the only thing I want to extract is the number 874659.29. This number varies among rows but it will always comes after ,"CashAmount": and a coma (,).
There will be only one ,"CashAmount": but several comas after.
dhfgdh&%^&%,"CashAmount":874659.29,"Hasdjhf"&^%^%
Therefore, I was wondering if I could use anything to only show the number in my output column.
Thanks in advance!
Here is another option for this just using some string manipulation.
declare #Details varchar(100) = 'dhfgdh&%^&%,"CashAmount":874659.29,"Hasdjhf"&^%^%'
select left(substring(#Details, CHARINDEX('CashAmount":', #Details) + 12 /*12 is the length of CashAmount":*/, LEN(#Details))
, charindex(',', substring(#Details, CHARINDEX('CashAmount":', #Details) + 12, LEN(#Details))) - 1)
You could use one of the split string functions as described here..
declare #string varchar(max)
set #string='dhfgdh&%^&%,"CashAmount":874659.29,"Hasdjhf"&^%^%'
select b.val from
[dbo].[SplitStrings_Numbers](#string,',')a
cross apply
(
select isnumeric(replace(a.item,'"CashAmount":',1)),replace(a.item,'"CashAmount":',1)
) b(chk,val)
where b.chk=1
Output:
874659.29
The above will work only if number comes after cashamount and before , and if it doesn't have any special characters..
if your number has special characters,you can use TRY_PARSE and check for NULL..
I have a table with details of family members staying in a particular locality. Since these are government data, it has lot mistakes. Like in one column 'houseno', there a 2 values 'Ti 303' and '303' which are same house numbers.
In the end, I want Ti 303 to be updated with '303'. (As these are family members living in same house)
Similarly 'P-101' and 'P/101' are same houseno's and I want it to be converted to either 'P-101' or 'P/101'. I tried difference, substring etc but of now use to me. Please help!
You just need to strip out the characters to compare the content?
CREATE FUNCTION dbo.FN_GetNumberPart (#strMixedString VARCHAR(200))
RETURNS VARCHAR(200)
AS
BEGIN
DECLARE #NumberPart INT
-- Get the next non numeric character position
SET #NumberPart = PATINDEX('%[^0-9]%', #strMixedString)
-- While there are non numeric characters remaining
WHILE #NumberPart > 0
BEGIN
-- Remove the non numeric character from the string
SET #strMixedString = STUFF(#strMixedString, #NumberPart , 1, '' )
-- Get the next non numeric character position
SET #NumberPart = PATINDEX('%[^0-9]%', #strMixedString)
END
-- Spit out the cleansed string
RETURN ISNULL(#strMixedString,0)
END
GO
SELECT dbo.FN_GetNumberPart(HouseNo)
from TblAddresses
You should use the REPLACE command. For the two examples give you could hard code it as follows:
select REPLACE('Ti 303','Ti ','')
select REPLACE('P-101','P-','P/')
You would use REPLACE in your UPDATE command and not as a SELECT obviously.
If you have a list of strings to replace in a column with an update then you could put these into a table. Then use this in your REPLACE command for the string pattern to be replaced.
I have a procedure in SQL Server 2008 ,which I have a query as below :
SELECT #symbol += N'' + acc_no FROM dbo.sav_acc_mcg where scheme_id = #scheme_id and status in (1,2) order by acc_no
which extracts all the "acc_no" from table and save it into #symbol. But the length of "acc_no" individually can vary. So I am thinking that I can use delimiter to separate each "acc_no" and then use a loop to extract every single "acc_no" by checking the the delimiter. Also I need to count the number of "acc_no".
If the length of each "acc_no" would have been same and without delimiter, e.g.10. I could have use the following code to count the number of "acc_no":
#count = len(#symbol)/10
And to extract each "acc_no" I could have use the following code :
#loop = 0
running the code below in a while loop until #loop<#count:
#acc_no = SUBSTRING(#symbol, (#loop*10)+1 , 10)
...................,etc
But due to the varying length of "acc_no" the above code will not work.
How to get the work done.
My requirement is like :
if
#symbol = PS-000001,GS-000002,CFS-000008,NS001-000016,CFS-000017,LS2-000019,......etc
I need to count the number of "acc_no" and then extract each "acc_no" for my other jobs.
Help is most welcomed.
I think this will do the job.
while #index1 < LEN(#symbol)
begin
set #index2 = CHARINDEX(',',#symbol,#index1)
set #op = substring(#symbol,#index1,#index2-#index1)
print #op
set #index1 = #index2+1
end