sql charindex extract number from string - sql

I have a column called original_filename which contains text. within the text there is a file ID which I want to extract. The description starts with "error_rows_" as shown below. However the file ID's vary in length i.e 999 to 999999 followed by additional text.
error_rows_90349_2014-04-10_00-00-00_Transaction-Login_TheHut.gpg
error_rows_904003_2014-04-10_12-00-00_Transaction-Login_TheHut.gpg
error_rows_90403_2014-04-10_12-00-00_Transaction-Registration_TheHut.gpg
error_rows_9060_2014-04-11_00-00-00_Transaction-Login_TheHut.gpg
Can someone help me with the sql to extract this. the end result should be:
90349
904003
90403
9060
I have been trying to use charindex withou success

Try this:
DECLARE #Test TABLE (TestData VARCHAR(500));
INSERT INTO #Test SELECT 'error_rows_90349_2014-04-10_00-00-00_Transaction-Login_TheHut.gpg';
INSERT INTO #Test SELECT 'error_rows_904003_2014-04-10_12-00-00_Transaction-Login_TheHut.gpg';
INSERT INTO #Test SELECT 'error_rows_90403_2014-04-10_12-00-00_Transaction-Registration_TheHut.gpg';
INSERT INTO #Test SELECT 'error_rows_9060_2014-04-11_00-00-00_Transaction-Login_TheHut.gpg';
SELECT
*,
CONVERT(INT, SUBSTRING(TestData, 12, CHARINDEX('_', TestData, 12) - 12))
FROM
#Test;
Results:
90349
904003
90403
9060

Related

Get every string before character in SQL Server

I got two record in table which is as below -:
1.123-21
2.123-21-30
How to query for all string before certain place of character . Below shown expected output
1. 123-21 -> 123
2. 123-21-30 ->123-21
How can I solve it?
DECLARE #T TABLE (Vals VARCHAR(100))
INSERT INTO #T(Vals) VALUES ('123-21') , ('123-21-30')
SELECT LEFT(Vals, LEN(Vals) - CHARINDEX('-', REVERSE(Vals)) )
FROM #T

Get values from 2nd occurrence

I have one question in SQL Server.
How to get values from 2nd occurrence from the _ symbol in SQL Server.
Table:Product_details
CREATE TABLE [dbo].[product_details](
[name] [varchar](500) NULL
) ON [PRIMARY]
GO
INSERT [dbo].[product_details] ([name]) VALUES (N'abc_xyz_pen')
INSERT [dbo].[product_details] ([name]) VALUES (N'def_rav_pen_two')
INSERT [dbo].[product_details] ([name]) VALUES (N'ade_rav_ted_ted_pen')
INSERT [dbo].[product_details] ([name]) VALUES (N'te_ty_te_de_rd_te')
Based on above table I want output like below
Name
pen
pen_two
ted_ted_pen
te_de_rd_te
I tried like below
select substring(name,charindex('_',name,1),len(name))
from product_details
Above query not giving exact result.
You may use:
SELECT
name,
SUBSTRING(name, CHARINDEX('_', name, CHARINDEX('_', name) + 1) + 1, LEN(name)) AS second
FROM [dbo].[product_details];
For an explanation, the above takes a substring of the name starting one position past the second underscore.
A couple of CHARINDEX's and STUFF works well here:
SELECT STUFF(pd.[name],1,CI2.I,'')
FROM dbo.product_details pd
CROSS APPLY (VALUES(CHARINDEX('_',pd.[name])))CI1(I)
CROSS APPLY (VALUES(CHARINDEX('_',pd.[name],CI1.I+1)))CI2(I);

How to replace delimited column value in SQL update query?

Values in Column are in format Name_city_age_ID (underscore separated).
Age was always blank. Other values may or not be blank. So values in column are like:
John_London__1223,
Mary_Paris__,
Dave____,
Smith____1012,
___2334
Now I have the age as 22 for all rows & I want to replace all values in the column, So the new columns should be:
John_London_22_1223,
Mary_Paris_22_,
Dave__22_,
Smith__22_1012,
__22_2334,
How to write the update query for this?
Using STUFF, but you should really normalize your data. This looks for the second instance of _ and adds 22.
declare #table table(col varchar(64))
insert into #table
values
('John_London__1223'),
('Mary_Paris__'),
('Dave____'),
('Smith____1012'),
('___2334')
select * from #table
--update the column
update #table
set col = stuff(col,charindex('_',col) + charindex('_',right(col,len(col) - charindex('_',col))) + 1,0,'22')
--see the results
select * from #table
Calling CHARINDEX function twice should do it. The following is the SELECT query for reviewing results, convert to UPDATE:
SELECT
str,
STUFF(str, CHARINDEX('_', str, CHARINDEX('_', str) + 1) + 1, 0, '22') AS newstr
FROM testdata
SQL Fiddle

How to manipulate comma-separated list in SQL Server

I have a list of values such as
1,2,3,4...
that will be passed into my SQL query.
I need to have these values stored in a table variable. So essentially I need something like this:
declare #t (num int)
insert into #t values (1),(2),(3),(4)...
Is it possible to do that formatting in SQL Server? (turning 1,2,3,4... into (1),(2),(3),(4)...
Note: I can not change what those values look like before they get to my SQL script; I'm stuck with that list. also it may not always be 4 values; it could 1 or more.
Edit to show what values look like: under normal circumstances, this is how it would work:
select t.pk
from a_table t
where t.pk in (#place_holder#)
#placeholder# is just a literal place holder. when some one would run the report, #placeholder# is replaced with the literal values from the filter of that report:
select t.pk
from a_table t
where t.pk in (1,2,3,4) -- or whatever the user selects
t.pk is an int
note: doing
declare #t as table (
num int
)
insert into #t values (#Placeholder#)
does not work.
Your description is a bit ridicuolus, but you might give this a try:
Whatever you mean with this
I see what your trying to say; but if I type out '#placeholder#' in the script, I'll end up with '1','2','3','4' and not '1,2,3,4'
I assume this is a string with numbers, each number between single qoutes, separated with a comma:
DECLARE #passedIn VARCHAR(100)='''1'',''2'',''3'',''4'',''5'',''6'',''7''';
SELECT #passedIn; -->: '1','2','3','4','5','6','7'
Now the variable #passedIn holds exactly what you are talking about
I'll use a dynamic SQL-Statement to insert this in a temp-table (declared table variable would not work here...)
CREATE TABLE #tmpTable(ID INT);
DECLARE #cmd VARCHAR(MAX)=
'INSERT INTO #tmpTable(ID) VALUES (' + REPLACE(SUBSTRING(#passedIn,2,LEN(#passedIn)-2),''',''','),(') + ');';
EXEC (#cmd);
SELECT * FROM #tmpTable;
GO
DROP TABLE #tmpTable;
UPDATE 1: no dynamic SQL necessary, all ad-hoc...
You can get the list of numbers as derived table in a CTE easily.
This can be used in a following statement like WHERE SomeID IN(SELECT ID FROM MyIDs) (similar to this: dynamic IN section )
WITH MyIDs(ID) AS
(
SELECT A.B.value('.','int') AS ID
FROM
(
SELECT CAST('<x>' + REPLACE(SUBSTRING(#passedIn,2,LEN(#passedIn)-2),''',''','</x><x>') + '</x>' AS XML) AS AsXml
) as tbl
CROSS APPLY tbl.AsXml.nodes('/x') AS A(B)
)
SELECT * FROM MyIDs
UPDATE 2:
And to answer your question exactly:
With this following the CTE
insert into #t(num)
SELECT ID FROM MyIDs
... you would actually get your declared table variable filled - if you need it later...

A query that will search for the highest numeric value in a table where the column has an alphanumeric sequence

I have a column (XID) that contains a varchar(20) sequence in the following format: xxxzzzzzz Where X is any letter or a dash and zzzzz is a number.
I want to write a query that will strip the xxx and evaluate and return which is the highest number in the table column.
For example:
aaa1234
bac8123
g-2391
After, I would get the result of 8123
Thanks!
A bit painful in SQL Server, but possible. Here is one method that assumes that only digits appear after the first digit (which you actually specify as being the case):
select max(cast(stuff(col, 1, patindex('%[0-9]%', col) - 1, '') as float))
from t;
Note: if the last four characters are always the number you are looking for, this is probably easier to do with right():
select max(right(col, 4))
Using Numbers table
declare #string varchar(max)
set #string='abc1234'
select top 1 substring(#string,n,len(#string))
from
numbers
where n<=len(#string)
and isnumeric(substring(#string,n,1))=1
order by n
Output:1234
Using PATINDEX you can achieve it, like this -
DECLARE #test table
(
id INT,
player varchar(100)
)
INSERT #test
VALUES (1,'aaa1234'),
(2,'bac8123'),
(3,'g-2391')
SELECT
MAX(CONVERT(INT, LTRIM(SUBSTRING(player, PATINDEX('%[0-9]%', player), LEN(player)))))
FROM #test
Try:
Select MAX(RIGHT(XID,17))
from table
You can also use this method
CREATE TABLE #Tmp
(
XID VARCHAR(20)
)
INSERT INTO #Tmp(XID)
VALUES ('aaa1234'), ('bac8123'), ('g-2391')
SELECT MAX(RIGHT(XID, LEN(XID) - 3))
FROM #Tmp