Select Part of Column - sql

I was wondering if anyone could help with a query to select part of a column.
The column 'criteriadata' contains data that would look like this:
CriteriaData
14 27 15 C
14 30 15 DD
14 38 15 Pass
14 33 15 Pass
How can I select just the data that appears after the number 15.
Many thanks.

SELECT RIGHT(CriteriaData,
LEN(CriteriaData) - CHARINDEX('15', CriteriaData, 1) - 2)
FROM TableName
WHERE CriteriaData LIKE '%15%';
SQL Fiddle Demo

declare #T table
(
CriteriaData varchar(20)
)
insert into #T values
('14 27 15 C'),
('14 30 15 DD'),
('14 38 15 Pass'),
('14 33 15 Pass')
select stuff(CriteriaData, 1, 3+charindex(' 15 ', CriteriaData), '')
from #T
Result:
---------
C
DD
Pass
Pass

If CriteriaCData always contains a pattern of 3 numbers of 2 numerics separated by a space then you always want to retrieve from 10th chars:
select SUBSTR(CriteriaCData, 10) from xxx
If you are under oracle min 10.g then use REGEXP_SUBSTR to retrieve the alpha pattern
SELECT upper(REGEXP_SUBSTR(CriteriaCData, '[a-zA-Z]*$')) FROM xxx

Since you seem to want everything from the ninth character onwards, you could use RIGHT and LEN
SELECT right([CriteriaData], len([CriteriaData]) - 9)
However, you'd be better off normalizing your data so it was already in a seperate column.

On oracle use LENGTH instead of LEN
SELECT substr(CriteriaData, 8, LENGTH(CriteriaData) - 9) from table

You should use substring with left functions
Have a look at this: How to extract this specific substring in SQL Server?
And this: http://msdn.microsoft.com/en-us/library/aa259342(v=sql.80).aspx

SELECT substring(criteriadata, 9, LEN(criteriadata)-8) from table
This assumes that the position of 15 is fixed.

Declare #x nvarchar(100) = '14 30 15 DD';
Select substring(#x, (select charindex('15',#x,1) + 2) ,len(#x));

I created a SQL function to split the criteria by the spaces and used the last remaining value after the last space.
create function dbo.getCriteria
(
#criteria varchar(500)
)
returns varchar(500)
begin
declare #space as int
select #space=charindex(' ', data) from mydata
while #space > 0
begin
set #criteria=substring(#criteria, #space + 1, len(#criteria))
select #space=charindex(' ', #criteria)
end
return #criteria
end
select dbo.getCriteria(data) from mydata

SELECT
RIGHT(CriteriaData, LEN(CriteriaData) - (CHARINDEX('15', CriteriaData, 1) - 2))
FROM
MyTable;

As I had trouble making prior answers work, I had to find my own and figure for future reference I'd leave it on Stack Overflow. My field has XML but it's an NVarchar field and should generalise just fine - if you have a clear criteria for left AND right surrounding strings.
It's not a complete match to this question but I hope it helps someone else who has huge strings in their columns and needs to snip out a string that varies in between two others!
WITH r
AS (
SELECT TOP 100 RIGHT(XMLData, LEN(XMLData)-CHARINDEX('<INVOICE_NO>', XMLData)-11) AS xmldata
FROM IncomingPartsInvoiceXML)
SELECT LEFT(xmldata, CHARINDEX('<\/INVOICE_NO>', XMLData)-1)
FROM r;

Related

Leading zero using sql server

I need to add leading zero in my records, but it doesn't work then I have no idea to solve this. the data as follow
textmess
convert
8
08
8
008
14
014
this is the query i have run
Select right('000' + rtrim(ltrim(cast(TEXTMESS as varchar(3)))), 3) convert, TEXTMESS from mytable
I thought it would work but it didn't work for first row, it should be 008 right? why the result is different with second row? . please help to solve this query
You can go for FORMAT and apply preceding 0.
DECLARE #table table(textmess int)
insert into #table
values (8),(8),(14)
SELECT textmess, FORMAT(textmess,'000') as convertedTExt from #table
textmess
convertedTExt
8
008
8
008
14
014
It seems that you have a special non-visible character in that row. First check that varchar value in hex to check which character code is it:
Select
right('000' + rtrim(ltrim(cast(TEXTMESS as varchar(3)))), 3) AS Converted,
TEXTMESS,
CONVERT(VARBINARY, TEXTMESS) AS HexValues
from
mytable
Seems that for a row you have 0x38 and for the other 0x381C. Assuming that the values are in ASCII, 38 is the 8 and 1C is the hex for symbol FS (file separator).
If you check any ASCII table online, you can see that the code for FS is 28, so just use REPLACE with CHAR(28). Check the result first:
Select
right('000' + rtrim(ltrim(cast(TEXTMESS as varchar(3)))), 3) AS Converted,
TEXTMESS,
REPLACE(TEXTMESS, CHAR(28), '') AS Replaced,
right('000' + rtrim(ltrim(cast(REPLACE(TEXTMESS, CHAR(28), '') as varchar(3)))), 3) AS ReplacedConverted
from
mytable
Then remove the character with UPDATE for all rows that have any FS:
UPDATE T SET
TEXTMESS = REPLACE(TEXTMESS, CHAR(28), '')
FROM
mytable AS T
WHERE
CHARINDEX(CHAR(28), TEXTMESS) > 0
try this
SELECT RIGHT('000'+CAST(textmess AS VARCHAR(3)),3)convertedText, textmess from mytable

Filter IDs with just numbers excluding letters

So I have results that begins with 2 letters followed by 3 numbers, for example:
ID_Sample
AB001
BC003
AB100
BC400
How can I do a query that ignores the letters and just looks up the numbers to do a filter? For example:
WHERE ID_Sample >= 100
I tried using a "Replace" to get rid of known letters, but I figured there might be a better way. For example:
Select
Replace(id_sample,'AB','')
Choosing the 3 numerals on the right would work too.
For your sample data, you can just start at the third character and convert to a number:
where try_convert(int, stuff(ID_Sample, 1, 2, '')) > 100
Or, if you know that the number is 3 characters:
where try_convert(int, right(ID_Sample, 3)) > 100
+1 for Gordon's answer. This is a fun problem that you can solve using TRANSLATE if you're using SQL 2017+.
First, in case you've never used it, Per BOL TRANSLATE:
Returns the string provided as a first argument after some characters
specified in the second argument are translated into a destination set
of characters specified in the third argument.2
This:
SELECT TRANSLATE('123AABBCC!!!','ABC','XYZ');
Returns: 123XXYYZZ!!!
Here's the solution using TRANSLATE:
-- Sample Data
DECLARE #t TABLE (ID_Sample CHAR(6))
INSERT #t (ID_Sample) VALUES ('AB001'),('BC003'),('AB100'),('BC400'),('CC555');
-- Solution
SELECT
ID_Sample = t.ID_Sample,
ID_Sample_Int = s.NewString
FROM #t AS t
CROSS JOIN (VALUES('ABCDEFGHIJKLMNOPQRSTUVWXYZ', REPLICATE(0,26))) AS f(S1,S2)
CROSS APPLY (VALUES(TRY_CAST(TRANSLATE(t.ID_Sample,f.S1,f.S2) AS INT))) AS s(NewString)
WHERE s.NewString >= 100;
Without the WHERE clause filter you get:
ID_Sample ID_Sample_Int
--------- -------------
AB001 1
BC003 3
AB100 100
BC400 400
CC555 555
... the WHERE clause filters out the first two rows.
Check these methods- Unit test also done!
Declare #Table as table(ID_Sample varchar(20))
set nocount on
Insert into #Table (ID_Sample)
Values('AB001'),('BC003'),('AB100'),('BC400')
--substring_method
select * from #Table
where try_cast(substring(ID_Sample,3,3) as int) >100
--right_method
select * from #Table
where try_cast(right(ID_Sample,3) as int) >100
--stuff_method
select * from #Table
where try_cast(stuff(ID_Sample,1,2,'') as int) >100
--replace_method
select * from #Table
where try_cast(replace(ID_Sample,left(ID_Sample,2),'') as int) >100

How to count string between string in sql

I have a data that having different length of value.
For example I have 2 rows of data:
CL-CI/PST/102/VII/2016
CL-CI/PST/0102/VII/2016
The difference between them is 102 (3 digits) and 0102 (4 digits)
I want in my SQL checking:
if (3Digits)
begin
....
end
else
begin
....
end
The records of data format is not fixed. Just not fixed on this string VII/2016 (based on month in roman numerals/year).
I know how to count the string is using LEN. But my problem is when I select top 1 of data. In this top 1 data that I got, I want to check dynamically if it is 4 digits / 3 digits that I got from that top 1. I'm stuck on this.
Try it like this
Easy: Just the length
DECLARE #s VARCHAR(100)='CL-CI/PST/0102/VII/2016';
SELECT LEN(CAST('<x>' + REPLACE(#s,'/','</x><x>')+'</x>' AS XML).value('/x[3]','varchar(max)'))
The result is 4
setbased approach
DECLARE #tbl TABLE(ID INT IDENTITY,YourString VARCHAR(100),OtherValue VARCHAR(100));
INSERT INTO #tbl(YourString,OtherValue) VALUES
('CL-CI/PST/102/VII/2016','With 3 digits')
,('CL-CI/PST/0102/VII/2016','With 4 digits');
WITH ExtendByPart3 AS
(
SELECT *
,CAST('<x>' + REPLACE(YourString,'/','</x><x>')+'</x>' AS XML).value('/x[3]','varchar(max)') AS Part3
FROM #tbl
)
SELECT *,LEN(Part3) AS LenPart3 FROM ExtendByPart3
The result
ID YourString OtherValue Part3 LenPart3
1 CL-CI/PST/102/VII/2016 With 3 digits 102 3
2 CL-CI/PST/0102/VII/2016 With 4 digits 0102 4
Btw: There are several questions about: How to access item X of a seperated string and most answers come with very complex CTEs, loops, CLR methods... This approach is direct and type safe. Change the nvarchar(max) of the .value() function to int and you would get the number - if needed.
I placed an answer to one of these questions myself, but - as this question is existing for years - the leading answers are very old fashioned and - IMO - outdated. But still it migth be worth reading this...
Retrieve all values
If you might be interested in your other values too, you could do this:
DECLARE #tbl TABLE(ID INT IDENTITY,YourString VARCHAR(100),OtherValue VARCHAR(100));
INSERT INTO #tbl(YourString,OtherValue) VALUES
('CL-CI/PST/102/VII/2016','With 3 digits')
,('CL-CI/PST/0102/VII/2016','With 4 digits');
WITH Splitted AS
(
SELECT CAST('<x>' + REPLACE(YourString,'/','</x><x>')+'</x>' AS XML) AS XMLData
FROM #tbl
)
SELECT XMLData.value('/x[1]','varchar(max)') AS Part1
,XMLData.value('/x[2]','varchar(max)') AS Part2
,XMLData.value('/x[3]','int') AS Number
,XMLData.value('/x[4]','varchar(max)') AS MonthRoman
,XMLData.value('/x[5]','int') AS TheYear
FROM Splitted
The result (attention: as returned as int the Number is without the leading zero)
Part1 Part2 Number MonthRoman TheYear
CL-CI PST 102 VII 2016
CL-CI PST 102 VII 2016
Perhaps case and like are sufficient:
select (case when col like '%/%/[0-9][0-9][0-9]/%' then <3 digit stuff>
when col like '%/%/[0-9][0-9][0-9][0-9]/%' then <4 digit stuff>
end)

Query to pad left of a field with 0's [duplicate]

This question already has answers here:
Formatting Numbers by padding with leading zeros in SQL Server
(14 answers)
Closed 7 years ago.
I have been working on a query (in sql Server TSQL) which fills left of a number with 0's so output is always 5 digit.
So:
Select MuNumber From Mytable
for data 11,011,2132,1111
Creates output like
00011
02134
01111
I tried Lpad Function but numer of 0's can be different.
if Munumber is 1 we need 0000 and If MyNumber is 34 we need 000
Assuming that MuNumber is VARCHAR simply use RIGHT
SELECT RIGHT('00000' + MuNumber, 5)
FROM Mytable
Otherwise you need to convert it first
SELECT RIGHT('00000' + CONVERT(VARCHAR(5), MuNumber), 5)
FROM Mytable
And in general you can use this pattern:
DECLARE #num INT = 10;
SELECT RIGHT(REPLICATE('0', #num) + CONVERT(VARCHAR(5), MuNumber), #num)
FROM Mytable
Try this
select right('00000'+cast(col as varchar(5)),5) from table
You can use the user defined function udfLeftSQLPadding where you can find the source codes at SQL Pad Leading Zeros
After you create the function on your database, you can use it as follows
select
dbo.udfLeftSQLPadding(MuNumber,5,'0')
from dbo.Mytable
Another option:
declare #n int = 6
select stuff(replicate('0', #n), 6-len(n), len(n), n)
from (values('123'), ('2493'), ('35')) as x(n)

SqlServer - Concatenate an integer

I'm look for any help to concatenate an integer.
Example:
In a company a employee as a employee number.
And is number is 140024.
Now, the number 14 is the year (depending on the date), and it needs to be assigned automatically. The other number 0024 is my problem. I could get the number 24 but how can I add the 00 or 000 if the number is less than 10?
So I need help to concatenate all this. And also wanted to get it as an INT to make it as a primary key.
DECLARE #Your_Number INT = 24;
SELECT CAST(RIGHT(YEAR(GETDATE()), 2) AS NVARCHAR(2))
+ RIGHT('000000000' + CAST(#Your_Number AS NVARCHAR), 4) --<-- This 4
RESULT: 140024
The Number 4 Decides how many Total digits you want after the Year Digits.
you have two choice : working with varchar or int itself.
Example :
select cast(14 as char(2)) + right('0000' + cast(24 as varchar(4)),4)
or with int
select 14 * 10000 + 24
Where 10000 of course is the number you can have max. It could be 100, 1000 or more. But your number of digit is probably fixed so it should be fixed too.
try this..
CREATE FUNCTION [dbo].[fn_GetAutoGeneratedID]
(
#strPart VARCHAR(20),#strSeprator VARCHAR(5),#intPart VARCHAR(10)
)RETURNS VARCHAR(20)
AS
BEGIN
DECLARE #prefix VARCHAR(10)
SET #prefix=(SELECT CASE LEN(#intPart)
WHEN 1 THEN #strSeprator+'0000'+#intPart
WHEN 2 THEN #strSeprator+'000'+#intPart
WHEN 3 THEN #strSeprator+'00'+#intPart
WHEN 4 THEN #strSeprator+'0'+#intPart
ELSE #strSeprator+#intPart
END)
RETURN(SELECT #strPart+#prefix);
END
now call it as..
SELECT #MyNum=dbo.fn_GetAutoGeneratedID (#yourMonthPart,'',#YourNextpart )
Declare #i int=24
select replicate('0',4-len(cast(#i as varchar(10))))+cast(#i as
varchar(10))