TSQL - Remove Everything after the last period - sql

I have a column string that may be one of the following.
10.0.2531.0
10.50.2500
10.0.2531.60
My requirement is, if there are 3 periods/decimal points, remove the last period/decimal and everything after that.
If I use the following, this will take care of the first row where there is only ".0", however, it does not work for the third row.
select
case
when right(column_1,2) = '.0' then left(column_1,len(column_1)-2)
else column_1 end,
FROM
table_1
I also tried the following but that didn't work.
select
case
when right(column_1,2) = '.' then left(column_1,len(column_1)-2)
when right(column_1,3) = '.' then left(column_1,len(column_1)-3)
else column_1 end,
FROM
table_1
The number after the third period/decimal may be a 0 or another number.

The following works, under the assumption that there are never five periods:
select (case when ip like '%.%.%.%'
then left(ip, len(ip) - charindex('.', reverse(ip))
else ip
end) as firstThree

Use a combination of charindex and substring.
SQL Fiddle
select reverse(substring(reverse(column_1), charindex('.',reverse(column_1))+1, len(column_1)))
from table_1
where len(column_1) - len(replace(column_1,'.','')) = 3

Related

How to ignore specific string value when using pattern and patindex function in SQL Server Query?

I have this query here.
WITH Cte_Reverse
AS (
SELECT CASE PATINDEX('%[^0-9.- ]%', REVERSE(EmailName))
WHEN 0
THEN REVERSE(EmailName)
ELSE left(REVERSE(EmailName), PATINDEX('%[^0-9.- ]%', REVERSE(EmailName)) - 1)
END AS Platform_Campaign_ID,
EmailName
FROM [Arrakis].[xtemp].[Stage_SendJobs_Marketing]
)
SELECT REVERSE(Platform_Campaign_ID) AS Platform_Campaign_ID, EmailName
FROM Cte_Reverse
WHERE REVERSE(Platform_Campaign_ID) <> '2020'
AND REVERSE(Platform_Campaign_ID) <> ''
AND LEN(REVERSE(Platform_Campaign_ID)) = 4;
It is working for the most part, below is a screenshot of the result set.
The query I posted above extracts the 4 numbers to the right out of the initial value that is set for the column I am extracting out of. But I am unable to figure out how I can also have the query ignore cases when the right most value is -v2, -v1, etc. essentially anything with -v and whatever number version it is.
If you want four digits, then one method is:
select substring(emailname, patindex('%[0-9][0-9][0-9][0-9]%', emailname), 4)

SQL Server - select substring of all characters following last hyphen

I am working with a database of products, trying to extract the product color from a combined ID/color code column where the color code is always the string following the last hyphen in the column. The issue is that the number of hyphens, product ID, and color code can all be different.
Here are four examples:
ABC123-001
BCD45678-0165
S-XYZ999-M2235
A-S-ABC123-001
The color codes in this case would be 001, 0165, M2235, and 001. What would be the best way to select these into their own column?
I think the following does what you want:
select right(col, charindex('-', reverse(col)) - 1)
In the event that you might have no hyphens in the value, then use a case:
select (case when col like '%-%'
then right(col, charindex('-', reverse(col)) - 1)
else col
end)
It is great to check whether the hyphen exists or not in the string, to avoid the following error:
Invalid length parameter passed to the right function.
SELECT CASE WHEN Col like '%\%' THEN RIGHT(Col,CHARINDEX('\',REVERSE(Col))-1) ELSE '' END AS ColName

Removing Characters From SQL String (Search)

Should be a pretty simple one today. I have a column with a list of contracts:
As you see, some contracts have a "-...." at the end. I need to removed this and any character after this (see desired output). Unfortunately, it's not just 1 character (could be multiple/differenct #s). So I imagine it's going to be a right/len/search combo.
Thoughts?
If the contracts all have the same form, the following is almost standard SQL for doing what you want:
select (case when CTNumber like '%-%-%'
then left(CTNumber, 7)
else CTNumber
end) as DesiredOutput
from t
The like syntax is standard, the case is standard, and most databases have a left() function. This does assume that the form of the CTNumber is such that you always want the first seven characters.
You can use patindex to confirm the presence of two dashes. With a double charindex, you can then return the part of the string before the second dash:
select case
when patindex('%-%-%', col1) > 0 then
left(col1, charindex('-', col1, charindex('-', col1) + 1) - 1)
else col1
end as col1
from dbo.YourTable

How to quickly compare many strings?

In SQL Server, I have a string column that contains numbers. Each entry I need is only one number so no parsing is needed. I need some way to find all rows that contain numbers from 400 to 450. Instead of doing:
...where my stringcolumn like '%400%' or stringcolumn like '%401%' or stringcolumn like '%402%' or ...
is there a better that can save on some typing?
There are also other values in these rows such as: '5335154', test4559#me.com', '555-555-5555'. Filtering those out will need to be taken into account.
...where stringcolumn like '4[0-4][0-9]' OR stringcolumn = '450'
You don't need the wildcard if you want to restrict to 3 digits.
Use regex to accomplish this.
...where stringcolumn like '4[0-4][0-9]' OR stringcolumn like '450'
one way
WHERE Column like '%4[0-4][09]%'
OR Column LIKE '%500%'
keep in mind that this will pick anything with the number in it, so 5000 will be returned as well
I would do the following:
select t.*
from (select t.*,
(case when charindex('4', col) > 0
then substrint(col, charindex('4', col), charindex('4', col) + 2)
end) as col4xx
from t
) t
where (case when isnumeric(col4xx) = 1
then (case when cast(col4xx as int) between 400 and 450 then 'true'
end)
end) = 'true'
I'm not a fan of having case statements in WHERE clauses. However, to ensure conversion to a number, this is needed (or the conversion could become a column in another subquery). Note that the following is not equivalent:
where col4xx between '400' and '450'
Since the string '44A' would match.

sql with <> and substring function

The output of query has to return records where company is not equal to 'CABS' OR substring of company until empty space (eg CABS NUTS).The company name can the CABS, COBS, CABST , CABS NUTS , CAB
SELECT *
FROM records
WHERE UPPER(SUBSTR(company, 0, (INSTR(company,' ')-1))) <> 'CABS'
OR COMPANY <> 'CABS'
But the above query is returing CABS NUTS along with COBS , CAB.
I tried using "LIKE CABS" it looks fine but if the company name is "CAB" it will not return "CABS" and CABS NUTS because of like. So LIKE is completely ruled out.
Can anyone please suggest me.
So you want all records where the first 4 characters of the Company field are not "CABS". Okay.
WHERE left(company, 4) != 'CABS'
SELECT
*
FROM
Records
WHERE
LEFT(Company, 4) <> 'CABS'
AND Company <> 'CABS'
Note: Basic TSQL String Comparison is case-insensitive
Can quite work out which ones you do want returns, but have you considered LIKE 'CABS %'
select * from records where company NOT IN (SELECT company
FROM records
WHERE UPPER(SUBSTR(company, 0, (INSTR(company,' ')-1))) = 'CABS'
OR COMPANY = 'CABS')
I think this will fetch the desired records from the records table
RECORDS:
COMPANY
=====================
CAB
CABST
COBS
First, I think you should use AND instead of OR in your compound condition.
Second, you could simplify the condition this way:
WHERE UPPER(SUBSTR(company, 0, (INSTR(company || ' ',' ') - 1))) <> 'CABS'
That is, the company <> 'CABS' part is not needed in this case.
The problem you are getting comes about because the result of the SUBSTR is null if there is not a space. And thanks to three value logic, the result of some_var <> NULL is NULL, rather than TRUE as you might expect.
And example of this is shown by the query below:
with mytab as (
select 1 as myval from dual union all
select 2 as myval from dual union all
select null as myval from dual
)
select *
from mytab
where myval = 1
union all
select *
from mytab
where myval <> 1
This example will only return two rows rather than three rows that you might expect.
There are several ways to rewrite the condition to make it ignore the null result from the substr function. These are listed below. However, as mentioned by one of the other respondents, the two conditions need to be joined using the AND operator rather than OR.
Firstly, you could explicitly check that the column has a space in it using the set of conditions below:
(INSTR(company,' ') = 0 or
UPPER(SUBSTR(company, 0, (INSTR(company,' ')-1))) <> 'CABS') and
COMPANY <> 'CABS'
Another option would be to use the LNNVL function. This is a function that I only recently found out about. It return TRUE from a condition when the result of the condition provided as the input is FALSE or NULL.
lnnvl(UPPER(SUBSTR(company, 0, (INSTR(company,' ')-1))) = 'CABS') and
COMPANY <> 'CABS'
And another option (which would probably be my preferred option) is to use the REGEXP_LIKE function. This is simple, to the point and easy to read.
WHERE not regexp_like(company, '^CABS( |$)')