Silly TSQL Question - Taking (N) Characters in Select Statement - sql-server

I have a select statement where I want to take 100 characters from a field. Is there an easy way to do this?
Here is some pseudo code below.
Select substring(0, 100, longField)
from myTable

You've got it. Use the SUBSTRING() method. This will work on any string/character/binary/image datatypes.
DECLARE #str varchar(1000);
SELECT #str = 'foobar-booz-baz-cowboys';
SELECT SUBSTRING (#str, 0, 10);
-- returns foobar-boo
--from a table:
SELECT SUBSTRING(CustomerName,0,100)
FROM MyTable;

Your pseudocode is pretty close.
select substring(longField, 0, 100)
from myTable
(Just for reference)
SQL Substring::
substring(expression, starting_pos, length)

The easiest way is using LEFT (Transact-SQL):
SELECT
LEFT(longField,100) AS longField, ...
FROM myTable
WHERE...

Related

Split string to array using delimiter, getting second to last element in SELECT Statement

Heads!
In my database, I have a column that contains the following data (examples):
H-01-01-02-01
BLE-01-03-01
H-02-05-1.1-03
The task is to get the second to last element of the array if you would split that using the "-" character. The strings are of different length.
So this would be the result using the above mentioned data:
02
03
1.1
Basically I'm searching for an equivalent of the following ruby-statement for use in a Select-Statement in SQL-Server:
"BLE-01-03-01".split("-")[-2]
Is this possible in any way in SQL Server? After spending some time searching for a solution, I only found ones that work for the last or first element.
Thanks very much for any clues or solutions!
PS: Version of SQL Server is Microsoft SQL Server 2012
As an alternative you can try this:.
--A mockup table with some test data to simulate your issue
DECLARE #mockupTable TABLE (ID INT IDENTITY, YourColumn VARCHAR(50));
INSERT INTO #mockupTable VALUES
('H-01-01-02-01')
,('BLE-01-03-01')
,('H-02-05-1.1-03');
--The query
SELECT CastedToXml.value('/x[sql:column("CountOfFragments")-1][1]','nvarchar(10)') AS TheWantedFragment
FROM #mockupTable t
CROSS APPLY(SELECT CAST('<x>' + REPLACE(t.YourColumn,'-','</x><x>') + '</x>' AS XML))A(CastedToXml)
CROSS APPLY(SELECT CastedToXml.value('count(/x)','int')) B(CountOfFragments);
The idea in short:
The first APPLY will transform the string to a XML like this
<x>H</x>
<x>01</x>
<x>01</x>
<x>02</x>
<x>01</x>
The second APPLY will xquery into this XML to get the count of fragments. As APPLY will add this as a column to the result set, we can use the value using sql:column() to get the wanted fragment by its position.
As I wrote in my comment - using charindex with reverse.
First, create and populate sample table (Please save us this step in your future questions):
DECLARE #T AS TABLE
(
Col Varchar(100)
);
INSERT INTO #T (Col) VALUES
('H-01-01-02-01'),
('BLE-01-03-01'),
('H-02-05-1.1-03');
The query:
SELECT Col,
LEFT(RIGHT(Col, AlmostLastDelimiter-1), AlmostLastDelimiter - LastDelimiter - 1) As SecondToLast
FROM #T
CROSS APPLY (SELECT CharIndex('-', Reverse(Col)) As LastDelimiter) As A
CROSS APPLY (SELECT CharIndex('-', Reverse(Col), LastDelimiter+1) As AlmostLastDelimiter) As B
Results:
Col SecondToLast
H-01-01-02-01 02
BLE-01-03-01 03
H-02-05-1.1-03 1.1
Similar to Zohar's solution, but using CTEs instead of CROSS APPLY to prevent redundancy. I personally find this easier to follow, as you can see what happens in each step. Doesn't make it a better solution though ;)
DECLARE #strings TABLE (data VARCHAR(50));
INSERT INTO #strings VALUES ('H-01-01-02-01') , ('BLE-01-03-01'), ('H-02-05-1.1-03');
WITH rev AS (
SELECT
data,
REVERSE(data) AS reversed
FROM
#strings),
first_hyphen AS (
SELECT
data,
reversed,
CHARINDEX('-', reversed) + 1 AS first_pos
FROM
rev),
second_hyphen AS (
SELECT
data,
reversed,
first_pos,
CHARINDEX('-', reversed, first_pos) AS second_pos
FROM
first_hyphen)
SELECT
data,
REVERSE(SUBSTRING(reversed, first_pos, second_pos - first_pos)) AS result
FROM
second_hyphen;
Results:
data result
H-01-01-02-01 02
BLE-01-03-01 03
H-02-05-1.1-03 1.1
Try this
declare #input NVARCHAR(100)
declare #dlmt NVARCHAR(3);
declare #pos INT = 2
SET #input=REVERSE(N'H-02-05-1.1-03');
SET #dlmt=N'-';
SELECT
CAST(N'<x>'
+ REPLACE(
(SELECT REPLACE(#input,#dlmt,'#DLMT#') AS [*] FOR XML PATH(''))
,N'#DLMT#',N'</x><x>'
) + N'</x>' AS XML).value('/x[sql:variable("#pos")][1]','nvarchar(max)');

SQL Server : Replace (Charindex)

I have a SQL Server table with numbers in column no:
12345670000115
14245670000116
58492010000118
I need a function that will remove one number 1 from right side of number, so result must be like:
1234567000015
1424567000016
5849201000018
I find some solutions to use charindex() with substring(), but my SQL skills are poor so I really need help.
Thanks
Assuming this is varchar data here is an easy way to accomplish this. BTW, I would suggest you not use column names like 'no'. It is a reserved word and it is horribly ambiguous. Does that mean number or the opposite of yes? If it is number as I assume it would be better to name the column with an indication of what the number is. PartNumber, ItemNumber, CatalogNumber whatever...
LEFT(no, len(no) - 2) + RIGHT(no, 1)
Try to use this query:
declare #charToReplace char = '1'
select REVERSE(stuff(REVERSE(no), charindex(#charToReplace, REVERSE(no)), 1, ''))
from table
or
declare #charToReplace char = '1'
declare #tmp_table TABLE (NO varchar(16))
insert into #tmp_table
select REVERSE(NO)
from yourtable
select REVERSE(stuff(NO, charindex(#charToReplace, NO), 1, ''))
For your particular data, if the numbers fit a BIGINT, one easy way is to treat them like numbers:
Setup
create table #tmp (
number VARCHAR(16)
)
insert into #tmp values ('12345670000115'), ('14245670000116'), ('58492010000118')
GO
Script:
select number, cast( (cast(number AS bigint) - 100) / 100 * 10 + cast(number AS bigint) % 100 as VARCHAR(16))
from #tmp
GO
I resolve problem. There is answer in which I remove one character 1 and update whole table. Thanks all for help!
Update myTableName
set barcode=substring(barcode,1,11)+substring(barcode,13,1)
where len(barcode)>= 14

MSSQL select substring according to this pattern

I have to ask you for something which is connetced with MSSQL.
So, I've got one column named Command(VARCHAR) which is a part of some table named TB_Commander.
This Column include results for example like (rows):
1.Delete o:2312312, c=312321
2.Add o:342342344, c=5
BTW. The thing I'd like to do is select substring from this rows which include only 'o:2312312' and for row number 2, only 'o:342342344'.
I'm stuck over here:
select
SUBSTRING(Command,PATINDEX('%1%',Command),
CHARINDEX(',',Command,PATINDEX('%o=%',Command))-0) as OperationID
from TB_Commander
where IdRow = 921321
Sorry for my english...
Thanks for any hand...
Try this ;)
select
substring(command,
patindex('%o:%', command) - 2,
patindex('%, c%', command)) as OperationID
from TB_Commander
where IdRow = 921321
This solution returns only the data you need, taking in to account length of patterns you use to extract the needed data:
SELECT
SUBSTRING(command,
PATINDEX('%o:%', command) + LEN('o:'),
PATINDEX('%, c%', [FiscalizationRequest]) - PATINDEX('%o:%',[FiscalizationRequest]) - LEN('o:')
) as OperationID
FROM TB_Commander;
declare #i int
declare #str varchar(1000)
set #str='interesting data'
declare #pattern varchar(1000)
set #pattern='eres'
SELECT #i=PATINDEX('%ter%', #str);
select substring(#str,#i-4,len(#pattern)+4)

How to split a string after specific character in SQL Server and update this value to specific column

I have table with data 1/1 to 1/20 in one column. I want the value 1 to 20 i.e value after '/'(front slash) is updated into other column in same table in SQL Server.
Example:
Column has value 1/1,1/2,1/3...1/20
new Column value 1,2,3,..20
That is, I want to update this new column.
Try this:
UPDATE YourTable
SET Col2 = RIGHT(Col1,LEN(Col1)-CHARINDEX('/',Col1))
Please find the below query also split the string with delimeter.
Select Substring(#String1,0,CharIndex(#delimeter,#String1))
From: http://www.sql-server-helper.com/error-messages/msg-536.aspx
To use function LEFT if not all data is in the form '1/12' you need this in the second line above:
Set Col2 = LEFT(Col1, ISNULL(NULLIF(CHARINDEX('/', Col1) - 1, -1), LEN(Col1)))
SELECT SUBSTRING(ParentBGBU,0,CHARINDEX('-',ParentBGBU,0)) FROM dbo.tblHCMMaster;
I know this question is specific to sql server, but I'm using postgresql and came across this question, so for anybody else in a similar situation, there is the split_part(string text, delimiter text, field int) function.
Maybe something like this:
First some test data:
DECLARE #tbl TABLE(Column1 VARCHAR(100))
INSERT INTO #tbl
SELECT '1/1' UNION ALL
SELECT '1/20' UNION ALL
SELECT '1/2'
Then like this:
SELECT
SUBSTRING(tbl.Column1,CHARINDEX('/',tbl.Column1)+1,LEN(tbl.Column1))
FROM
#tbl AS tbl
SELECT emp.LoginID, emp.JobTitle, emp.BirthDate, emp.ModifiedDate ,
CASE WHEN emp.JobTitle NOT LIKE '%Document Control%' THEN emp.JobTitle
ELSE SUBSTRING(emp.JobTitle,CHARINDEX('Document Control',emp.JobTitle),LEN('Document Control'))
END
,emp.gender,emp.MaritalStatus
FROM HumanResources.Employee [emp]
WHERE JobTitle LIKE '[C-F]%'
Use CHARINDEX. Perhaps make user function. If you use this split often.
I would create this function:
CREATE FUNCTION [dbo].[Split]
(
#String VARCHAR(max),
#Delimiter varCHAR(1)
)
RETURNS TABLE
AS
RETURN
(
WITH Split(stpos,endpos)
AS(
SELECT 0 AS stpos, CHARINDEX(#Delimiter,#String) AS endpos
UNION ALL
SELECT endpos+1, CHARINDEX(#Delimiter,#String,endpos+1)
FROM Split
WHERE endpos > 0
)
SELECT 'INT_COLUMN' = ROW_NUMBER() OVER (ORDER BY (SELECT 1)),
'STRING_COLUMN' = SUBSTRING(#String,stpos,COALESCE(NULLIF(endpos,0),LEN(#String)+1)-stpos)
FROM Split
)
GO

How do I extract part of a string in t-sql

If I have the following nvarchar variable - BTA200, how can I extract just the BTA from it?
Also, if I have varying lengths such as BTA50, BTA030, how can I extract just the numeric part?
I would recommend a combination of PatIndex and Left. Carefully constructed, you can write a query that always works, no matter what your data looks like.
Ex:
Declare #Temp Table(Data VarChar(20))
Insert Into #Temp Values('BTA200')
Insert Into #Temp Values('BTA50')
Insert Into #Temp Values('BTA030')
Insert Into #Temp Values('BTA')
Insert Into #Temp Values('123')
Insert Into #Temp Values('X999')
Select Data, Left(Data, PatIndex('%[0-9]%', Data + '1') - 1)
From #Temp
PatIndex will look for the first character that falls in the range of 0-9, and return it's character position, which you can use with the LEFT function to extract the correct data. Note that PatIndex is actually using Data + '1'. This protects us from data where there are no numbers found. If there are no numbers, PatIndex would return 0. In this case, the LEFT function would error because we are using Left(Data, PatIndex - 1). When PatIndex returns 0, we would end up with Left(Data, -1) which returns an error.
There are still ways this can fail. For a full explanation, I encourage you to read:
Extracting numbers with SQL Server
That article shows how to get numbers out of a string. In your case, you want to get alpha characters instead. However, the process is similar enough that you can probably learn something useful out of it.
substring(field, 1,3) will work on your examples.
select substring(field, 1,3) from table
Also, if the alphabetic part is of variable length, you can do this to extract the alphabetic part:
select substring(field, 1, PATINDEX('%[1234567890]%', field) -1)
from table
where PATINDEX('%[1234567890]%', field) > 0
LEFT ('BTA200', 3) will work for the examples you have given, as in :
SELECT LEFT(MyField, 3)
FROM MyTable
To extract the numeric part, you can use this code
SELECT RIGHT(MyField, LEN(MyField) - 3)
FROM MyTable
WHERE MyField LIKE 'BTA%'
--Only have this test if your data does not always start with BTA.
declare #data as varchar(50)
set #data='ciao335'
--get text
Select Left(#Data, PatIndex('%[0-9]%', #Data + '1') - 1) ---->>ciao
--get numeric
Select right(#Data, len(#data) - (PatIndex('%[0-9]%', #Data )-1) ) ---->>335

Resources