count # of times a text appears in a str - sql-server

I am trying to search this string(TenderString1) for SPT. This just outputs the number of characters - so if there were 1 SPT in this string it would return 3 (number of characters). So I am attempting to divide the result by the length of SPT (3) to get the number of occurrences of SPT in the string but it is not returning the correct number
(LEN(TenderString1) - LEN(REPLACE(TenderString1, 'SPT', '')) / len('SPT'))Test
TenderString1 Column:
UAD,MTY,CL,CLTG,OFD,OFD,SPT,SL
Answer should be: 1

If you want the number of times a substring appears in a string when you have something delimited like you do, something like this would do it:
SELECT COUNT(*) FROM STRING_SPLIT(',UAD,MTY,CL,CLTG,OFD,OFD,SPT,SL,SPT,SPT', ',') WHERE value='SPT'
This one returns a 3.
And here's it is with some data:
SELECT
VAL, (SELECT COUNT(*) FROM STRING_SPLIT(VAL, ',') WHERE value='SPT') CNT
FROM
(
SELECT ',UAD,MTY,CL,CLTG,OFD,OFD,SPT,SL,SPT,SPT' AS VAL
UNION
SELECT ',UAD,MTY,CL,CLTG,OFD,OFD,SPT,SL,SPT,SPT,SPT' AS VAL
) A

The division is of higher precedence than subtraction, your code executes LEN(REPLACE(TenderString1, 'SPT', '')) / len('SPT') first and then the result is subtracted from LEN(TenderString1). You could use parenthesis to perform the subtraction first and then divide the result by len('STR')..pay attention that LEN() ignores trailing spaces, so better to prevent wrong calculations (when the searched term is at the end of the string/value) by appending another character at the end of the column value/string.
select TenderString1,
(LEN(TenderString1) - LEN(REPLACE(TenderString1, 'SPT', '')) / len('SPT')) as Test,
(LEN(TenderString1) - LEN(REPLACE(TenderString1, 'SPT', ''))) / len('SPT') as Test1,
(LEN(TenderString1+'.') - LEN(REPLACE(TenderString1+'.', 'SPT', ''))) / len('SPT') as SPToccurence
from
(values
(',UAD,MTY,CL,CLTG,OFD,OFD,SPT,SL'),
(',UAD,MTY,CL,CLTG,OFD,OFD,SL, SPT')
) as t(TenderString1);

Related

SQL Server - How to get last numeric value in the given string

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

SQL Query to Add Leading 0 to part of a column

I need to update a column in SQL to add a leading zero. Problem is this column has data in it in several formats.
0047
0070-0336
0025-0145
0032-0008
0033-0196 Johnson EEOC Matter
I need to add a zero before the last 4 digits, or rather just after the dash, but to only the rows that have the 4 digit - 4 digit format (and 4 -4 plus alpha). So it would look like:
0047
0070-00336
0025-00145
0032-00008
0033-00196 Johnson EEOC Matter
I have tried several UPDATE and RIGHT statements but cannot get the result I need.
what about REPLACE
SELECT REPLACE(YourField, '-', '-0');
FROM YourTable
This will replace the first occurrence of -
SELECT STUFF(YourField, CHARINDEX('-', YourField), 1, '-0')
But will fail if you have this case
0476 jhonso-jhonson
Not tested. Please test it before execution on your real data.
UPDATE yourTable
SET col = SUBSTRING(col, 0, CHARINDEX('-', col))
+ '-0' +
SUBSTRING(col, CHARINDEX('-', col) + 1, LEN(col) - CHARINDEX('-', col))
WHERE col LIKE N'____-____%'
This filters only rows with 4 characters, followed by -, followed by 4 characters, followed by anything. It sets the column in the following way: put the character from 0 till the first - as they are, append -0 (instead of -), then append the rest of column value as they are.
You can use the following expression:
SELECT IIF(CHARINDEX('-', #COL) <> 0,
STUFF(#COL, CHARINDEX('-', #COL), 1, '-0'),
#COL)
In case of a 4 digit - 4 digit, or 4 -4 plus alpha format, this will replace the first '-' with a '-0'.

select integer before a certain character

hie am trying to select the integer value before the char C in my SQL database table which contains the information below.
240mm2 X 15C WIRING CABLE
150mm2 X 3C flex
10mm2 x 4C swa
so far i have used the query
select left ('C',CHARINDEX ('C',product_name)) from product
and i get 'C' on my results which is correct. Now am stuck does anyone know how i can modify the above select query to get a result which only lists the integers for eg
15
3
4
Two observations: the integer before "C" has a space before it and there is no space between the integer and "C".
If these are generally true, then you can do what you want using substring_index():
select substring_index(substring_index(product_name, 'C', 1), ' ', -1) + 0 as thenumber
The + 0 simply converts the value to a number.
If you're doing this in SQL Server you could try the following:
Select Substring(product_name,
PATINDEX('% [0-9]%',product_name) + 1,
PATINDEX('%[0-9]C%',product_name) - PATINDEX('% [0-9]%',product_name)
) as num
from Product
This assumes that there is a space before the number and always a C after the number with no space.
It works out the starting point and then the length based on the start and end and performs a substring with the results.
You could use a combination of instring and substring.
First get the position of the C
Then substring till C
It goes like this:
SELECT INSTR('foobarbar', 'bar');
= 4
And then you select substring from 1 to 4.

SQL Server SELECT query ordering by substring

I have a column in a SQL Server table that has the following rows:
MyColumn : C1_xxx1,C2_xxx1,C3_xxx1,C1_xxx2,C1_xxx3,C3_xxx2 etc
It is a text column that contains strings that have the following format: CY_mystring where Y is a number from 1 to 5, followed by the '_' character then mystring that can have any value.
Is there a way to make a select return this column ordered as following:
C1_xxx1
C1_xxx2
C1_xxx3
......
C1_xxxn
C2_xxx1
......
C2_xxxn
C3_xxx1
.......
C3_xxxn
etc
Ordered by the CY_ substring.
thank you
This should do it .. (order first by the first two chars, and then by the last char (assuming that the final n is always one digit long))
SELECT
Column1
FROM
TABLENAME
ORDER BY
LEFT(Column1,2) ASC,
RIGHT(Column1,1) ASC
You say that Y is a number from 1 to 5 it's always one character long. Assuming the format is xY_xxxZ, you can order on Y then Z like:
order by
substring(MyColumn,2,1) -- Second digit
, right(MyColumn,1) -- Last digit
If Z can be longer than one character (i.e. 10 or higher) you can use pathindex to determine the number of digits at the end:
order by
substring(MyColumn,2,1) -- Second digit
, right(MyColumn, patindex('%[^0-9]%', reverse(MyColumn))-1) -- Digits at end

SQL Server: sort a column numerically if possible, otherwise alpha

I am working with a table that comes from an external source, and cannot be "cleaned". There is a column which an nvarchar(20) and contains an integer about 95% of the time, but occasionally contains an alpha. I want to use something like
select * from sch.tbl order by cast(shouldBeANumber as integer)
but this throws an error on the odd "3A" or "D" or "SUPERCEDED" value.
Is there a way to say "sort it like a number if you can, otherwise just sort by string"? I know there is some sloppiness in that statement, but that is basically what I want.
Lets say for example the values were
7,1,5A,SUPERCEDED,2,5,SECTION
I would be happy if these were sorted in any of the following ways (because I really only need to work with the numeric ones)
1,2,5,7,5A,SECTION,SUPERCEDED
1,2,5,5A,7,SECTION,SUPERCEDED
SECTION,SUPERCEDED,1,2,5,5A,7
5A,SECTION,SUPERCEDED,1,2,5,7
I really only need to work with the
numeric ones
this will give you only the numeric ones, sorted properly:
SELECT
*
FROM YourTable
WHERE ISNUMERIC(YourColumn)=1
ORDER BY YourColumn
select
*
from
sch.tbl
order by
case isnumeric(shouldBeANumber)
when 1 then cast(shouldBeANumber as integer)
else 0
end
Provided that your numbers are not more than 100 characters long:
WITH chars AS
(
SELECT 1 AS c
UNION ALL
SELECT c + 1
FROM chars
WHERE c <= 99
),
rows AS
(
SELECT '1,2,5,7,5A,SECTION,SUPERCEDED' AS mynum
UNION ALL
SELECT '1,2,5,5A,7,SECTION,SUPERCEDED'
UNION ALL
SELECT 'SECTION,SUPERCEDED,1,2,5,5A,7'
UNION ALL
SELECT '5A,SECTION,SUPERCEDED,1,2,5,7'
)
SELECT rows.*
FROM rows
ORDER BY
(
SELECT SUBSTRING(mynum, c, 1) AS [text()]
FROM chars
WHERE SUBSTRING(mynum, c, 1) BETWEEN '0' AND '9'
FOR XML PATH('')
) DESC
SELECT
(CASE ISNUMERIC(shouldBeANumber)
WHEN 1 THEN
RIGHT(CONCAT('00000000',shouldBeANumber), 8)
ELSE
shouoldBeANumber) AS stringSortSafeAlpha
ORDEER BY
stringSortSafeAlpha
This will add leading zeros to all shouldBeANumber values that truly are numbers and leave all remaining values alone. This way, when you sort, you can use an alpha sort but still get the correct values (with an alpha sort, "100" would be less than "50", but if you change "50" to "050", it works fine). Note, for this example, I added 8 leading zeros, but you only need enough leading zeros to cover the largest possible integer in your column.

Resources