case statement to delete extra spaces only when there is some - sql

I replace all blanks with # using this
SELECT *, REPLACE(NAME,' ','#') AS NAME2
which results miss#test#blogs############## (different number of #s dependent on length of name!
I then delete all # signs after the name using this
select *, substring(Name2,0,charindex('##',Name2)) as name3
which then gives my desired results of, for example MISS#test#blogs
However some wheren't giving this result, they are null. This is because annoyingly some rows in the sheet I have read in dont have the spaces after the name.
is there a case statement i can use so it only deletes # signs after the name if they are there in the first place?
Thanks

The function rtrim can be used to remove trailing spaces. For example:
select replace(rtrim('miss test blogs '),' ','#')
-->
'miss#test#blogs'
Example at SQL Fiddle.

try this:
Declare #t table (name varchar(100),title varchar(100),forename varchar(100))
insert into #t
values('a b c','dasdh dsalkdk asdhl','asd dfg sd')
SELECT REPLACE(REPLACE(REPLACE(LTRIM(RTRIM(name)),' ',' '+CHAR(7)),CHAR(7)+' ','') ,CHAR(7),'') AS Name,
REPLACE(REPLACE(REPLACE(LTRIM(RTRIM(title)),' ',' '+CHAR(7)),CHAR(7)+' ','') ,CHAR(7),'') AS title,
REPLACE(REPLACE(REPLACE(LTRIM(RTRIM(forename)),' ',' '+CHAR(7)),CHAR(7)+' ','') ,CHAR(7),'') AS forename
FROM #t WHERE
(CHARINDEX(' ',NAME) > 0 or CHARINDEX(' ',title) > 0 or CHARINDEX(' ',forename) > 0)
SQL Fiddle Demo

select name2, left(name2,len(name2)+1-patindex('%[^#]%',reverse(name2)+'.'))
from (
SELECT *, REPLACE(NAME,' ','#') AS NAME2
from t
) x;
Check this SQL Fiddle
For posterity, sample table:
create table t (name varchar(100));
insert t select 'name#name#ne###'
union all select '#name#name'
union all select 'name name hi '
union all select 'joe public'
union all select ''
union all select 'joe'
union all select 'joe '
union all select null
union all select ' leading spaces'
union all select ' leading trailing ';

Don't quite understand the question, but if the problem is there is not spaces after some names, can't you do this first:
SELECT *, REPLACE(NAME+' ',' ','#') AS NAME2
i.e., add a space to all names right off the bat?

I had this same problem some days ago.
Well actually, there's a quickly way to subtract the spaces from both the begin and end inside strings. In SQL Server, you can use the RTRIM and LTRIM for this. The first one supresses spaces from right side and the second supresses from left. But, if in your scenario also may exists more than one space in the middle of the string I sugest you take a look on this post on SQL Server Central: http://www.sqlservercentral.com/articles/T-SQL/68378/
There the script's author explain, in details, a good solution for this situation.

Related

get 1 email address from multiple delimiters

I have a column email with multiple delimiters like space ,/ , .
email
/john#thundergroup.com.mi/chris#cup.com.ey
r.Info#bc.com / rudi.an#yy.com
Dal#pema.com/Al#ama.com
/randi#mv.com
zul#sd.com/sat#sd.com/ faze#sd.com
My query:
select email,
CASE WHEN CHARINDEX(' ', email) > 0 THEN SUBSTRING(email, 0, CHARINDEX(' ', email)) ELSE
email END as Emailnew
FROM table
my output:
/john#thundergroup.com.mi/chris#cup.com.ey
r.Info#bc.com
Dal#pema.com/Al#ama.com
/randi#mv.com
zul#sd.com/sat#sd.com/ faze#sd.com
Please suggest changes so that in a single query I'm able to extract email
To get the first email always, you can try this below logic-
DEMO HERE
SELECT
CASE
WHEN CHARINDEX('/',email,2) = 0 THEN REPLACE(email,'/','')
ELSE REPLACE(SUBSTRING(email,0,CHARINDEX('/',email,2)),'/','')
END
FROM your_table
Output will be-
john#thundergroup.com.mi
r.Info#bc.com
Dal#pema.com
randi#mv.com
zul#sd.com
On modern SQL Servers try something like:
-- Setup...
create table dbo.Foo (
FooID int not null identity primary key,
Email nvarchar(100)
);
insert dbo.Foo (Email) values
('/john#thundergroup.com.mi/chris#cup.com.ey'),
('r.Info#bc.com / rudi.an#yy.com'),
('Dal#pema.com/Al#ama.com'),
('/randi#mv.com'),
('zul#sd.com/sat#sd.com/ faze#sd.com');
go
-- Demo...
select FooID, [Email]=value
from dbo.Foo
outer apply (
select top 1 value
from string_split(translate(Email, ' /', ';;'), ';')
where nullif(value, '') is not null
) Splitzville;
Which yields:
FooID Email
1 john#thundergroup.com.mi
2 r.Info#bc.com
3 Dal#pema.com
4 randi#mv.com
5 zul#sd.com
Requirements:
SQL Server 2016 and later for string_split().
SQL Server 2017 and later for translate().
If you want the first email only, use patindex():
select email,
left(email, patindex('%[^a-zA-Z0-9#.]%', email + ' ') - 1) as Emailnew
from table;
The pattern (a-zA-Z0-9#.) are valid email characters. You may have additional ones that you care about.
Unfortunately, I notice that some of your lists start with delimiter characters. In my opinion, the above works correctly by returning an empty value. That said, your desired results are to get the second value in that case.
So, you have to start the search at the first valid email character:
select t.email,
left(v.email1, patindex('%[^-_a-zA-Z0-9#.]%', v.email1 + ' ') - 1) as Emailnew
from t cross apply
(values (stuff(t.email, 1, patindex('%[-_a-zA-Z0-9#.]%', t.email) - 1, ''))) v(email1);
Here is a db<>fiddle.

I want to remove part of string from a string

Thank you in advance.
I want to remove string after . including ., but length is variable and string can be of any length.
1)Example:
Input:- SCC0204.X and FRK0005.X and RF0023.X and ADF1010.A and HGT9010.V
Output: SCC0204 and FRK0005 and RF0023 and ADF1010.A and HGT9010.V
I tried using the charindex but as the length keeps on changing i wasn't able to do it. I want to trim the values with ending with only X
Any help will be greatly appreciated.
Assuming there is only one dot
UPDATE TABLE
SET column_name = left(column_name, charindex('.', column_name) - 1)
For SELECT
select left(column_name, charindex('.', column_name) - 1) AS col
from your_table
Hope this helps. The code only trims the string when the value has a decimal "." in it and if that value is equal to .X
;WITH cte_TestData(Code) AS
(
SELECT 'SCC0204.X' UNION ALL
SELECT 'FRK0005.X' UNION ALL
SELECT 'RF0023.X' UNION ALL
SELECT 'ADF1010.A' UNION ALL
SELECT 'HGT9010.V' UNION ALL
SELECT 'SCC0204' UNION ALL
SELECT 'FRK0005'
)
SELECT CASE
WHEN CHARINDEX('.', Code) > 0 AND RIGHT(Code,2) = '.X'
THEN SUBSTRING(Code, 1, CHARINDEX('.', Code) - 1)
ELSE Code
END
FROM cte_TestData
If the criteria is only to replace remove .X then probably this should also work
;WITH cte_TestData(Code) AS
(
SELECT 'SCC0204.X' UNION ALL
SELECT 'FRK0005.X' UNION ALL
SELECT 'RF0023.X' UNION ALL
SELECT 'ADF1010.A' UNION ALL
SELECT 'HGT9010.V' UNION ALL
SELECT 'SCC0204' UNION ALL
SELECT 'FRK0005'
)
SELECT REPLACE (Code,'.X','')
FROM cte_TestData
Use LEFT String function :
DECLARE #String VARCHAR(100) = 'SCC0204.XXXXX'
SELECT LEFT(#String,CHARINDEX('.', #String) - 1)
I think your best bet here is to create a function that parses the string and uses regex. I hope this old post helps:
Perform regex (replace) in an SQL query
However, if the value you need to trim is constantly ".X", then you should use
select replace(string, '.x', '')
Please check the below code. I think this will help you.
DECLARE #String VARCHAR(100) = 'SCC0204.X'
IF (SELECT RIGHT(#String,2)) ='.X'
SELECT LEFT(#String,CHARINDEX('.', #String) - 1)
ELSE
SELECT #String
Update: I just missed one of the comments where the OP clarifies the requirement. What I put together below is how you would deal with a requirement to remove everything after the first dot on strings ending with X. I leave this here for reference.
;WITH cte_TestData(Code) AS
(
SELECT 'SCC0204.X' UNION ALL -- ends with '.X'
SELECT 'FRK.000.X' UNION ALL -- ends with '.X', contains multiple dots
SELECT 'RF0023.AX' UNION ALL -- ends with '.AX'
SELECT 'ADF1010.A' UNION ALL -- ends with '.A'
SELECT 'HGT9010.V' UNION ALL -- ends with '.V'
SELECT 'SCC0204.XF' UNION ALL -- ends with '.XF'
SELECT 'FRK0005' UNION ALL -- totally clean
SELECT 'ABCX' -- ends with 'X', not dots
)
SELECT
orig_string = code,
newstring =
SUBSTRING
(
code, 1,
CASE
WHEN code LIKE '%X'
THEN ISNULL(NULLIF(CHARINDEX('.',code)-1, -1), LEN(code))
ELSE LEN(code)
END
)
FROM cte_TestData;
FYI - SQL Server 2012+ you could simplify this code like this:
SELECT
orig_string = code,
newstring =
SUBSTRING(code, 1,IIF(code LIKE '%X', ISNULL(NULLIF(CHARINDEX('.',code)-1, -1), LEN(code)), LEN(code)))
FROM cte_TestData;
With SUBSTRING you can achieve your requirements by below code.
SELECT SUBSTRING(column_name, 0, CHARINDEX('.', column_name)) AS col
FROM your_table
If you want to remove fixed .X from string you can also use REPLACE function.
SELECT REPLACE(column_name, '.X', '') AS col

SQL Returning names with multiple spaces

I am looking to return all names with more than one space in a single field.
For example 'John Paul Smith'. Using SQL server management studio 2005
Example I have a patients table with forename and surname
I want to return all forenames that have example 'John Paul Smith' in one field.
The query given seems to work on the surname field but not the forename. I knot for certain that the forename columns has these types of data but it is returning no results.
Con
Oracle:
SELECT MyField
from MyTable
where REGEXP_INSTR (MyField, ' ', 1, 2, 0, 'i') > 0
SQL server:
SELECT MyField
from MyTable
where CHARINDEX(' ', MyField, charindex(' ',MyField)+1) > 0
MySQL
select MyField
from MyTable
where length(SUBSTRING_INDEX(MyField, ' ', 2)) < length(MyField)
Here are two solutions that in my opinion are easier to read/understand than JohnHC's.
It can't get any simpler. Use wildcards to search for (at least) two spaces.
SELECT * FROM your_table WHERE your_column LIKE '% % %';
Check the length after replacing the spaces
SELECT * FROM your_table WHERE LEN(your_column) - LEN(REPLACE(your_column, ' ', '')) >= 2;

how to replace a comma with single quote comma in SQLIN clause

Hi all I have a an where clause like below
select * from table1
where colum1 IN (?parameter)
when I pass the values to the parameter they show up like below
('1,2,3') but to execute the query I need to change the values as ('1','2','3')
is there a way to replace the commas with single quotes comma in IN clause directly?
There is one hack to do what you want, using like:
select *
from table1
where ',' || column1 || ',' like '%,' || (?parameter) || ',%';
This functions, but it will not make use of an index on column1. You should think about other solutions, such as:
Parsing the string into a table variable.
Using in with a fixed number of parameters.
Storing the values in a table.
There may be other Oracle-specific solutions as well.
Use MS SQL, you can convert it into table value and using join for your condition, I am not familiar oracle but you can find same way to do it.
DECLARE #IDs varchar(max) ='1,2,3';
;WITH Cte AS
(
SELECT
CAST('<ID>' + REPLACE( #IDs, ',' , '</ID><ID>') + '</ID>' AS XML) AS IDs
)
SELECT '''' + Split.a.value('.', 'VARCHAR(100)') +'''' AS ID FROM Cte
CROSS APPLY Cte.IDs.nodes('/ID') Split(a)
You can achieve it using with clause. Logic here is to convert each comma separated value into different row.
with temp_tab as (
select replace(regexp_substr(parameter, '[^,]+',1, level),'''','') as str
from dual
connect by level<= length(regexp_replace(parameter, '[^,]+'))+1 )
select * from table1 where column1 in (select str from temp_tab);

Extracting from text using tsql

I have the following string format in a Sql table column
[CID]: 267 [MID]: 319A [Name]: RJR
How can I extract only the value of MID which is 319A in select query so I can use the MID in a join.
In other words I need to extract the MID value from this text field to use it in a join. I copy/pasted the value and it looks like there are /n (new line) characters after each value.
Thanks in advance
you may try this one.
declare
#t varchar(100)
set #t = '[CID]: 267 [MID]: 319A [Name]: RJR';
select ltrim(rtrim(substring(#t,charindex('[MID]:',#t)+6,(charindex('[NAME]',#t))-(charindex('[MID]:',#t)+6))))
---------------------------------------------------------
319A
ltrim and rtrim will trim your 319A value.
you can try without them at start if you like.
Cheers
http://www.simple-talk.com/sql/t-sql-programming/tsql-regular-expression-workbench/
to add regex support to sql server
Rubular Regex to get you started:
\[MID\]: (.*) \[Name]:
Not clean at ALL, but if you need it in SQL, here you go:
Use
SUBSTRING ( value_expression , start_expression , length_expression )
and
LOCATE( string1, string2 [, start] )
together:
SUBSTRING(INPUT,
((SELECT LOCATE( 'MID]: ', INPUT ))+6),
((SELECT LOCATE( '[Name]', INPUT )) - ((SELECT LOCATE( 'MID]: ', INPUT ))+6))
depending where is taking place? If it is in a batch process, I would export those fields with an ID, write a perl one liner that extracts them, and then load them back to the db. it would be so much faster than using these functions.
if it is screen event, then I suggest breaking them into 3 columns instead, itll actully save you space.
Don't really think you need all these trimming and substring-ing functions.
USE tempdb;
GO
CREATE TABLE #t1
(
a INT,
b VARCHAR(64)
);
INSERT #t1 SELECT 1, '[CID]: 267 [MID]: 319A [Name]: RJR'
UNION ALL SELECT 2, '[CID]: 26232 [MID]: 229dd5A [Name]: RJ'
UNION ALL SELECT 3, 'Garbage that will not match';
CREATE TABLE #t2
(
c INT,
d VARCHAR(32)
);
INSERT #t2 SELECT 4, '319A'
UNION ALL SELECT 5, '229dd5A'
UNION ALL SELECT 6, 'NO MATCH';
SELECT t1.a, t1.b, t2.c, t2.d
FROM #t1 AS t1
INNER JOIN #t2 AS t2
ON t1.b LIKE '%`[MID`]: ' + t2.d + ' %' ESCAPE '`'
GO
DROP TABLE #t1, #t2;
If you have no idea how many spaces might be between [MID]: and the start of your value, or the end of your value and the start of the next [, and assuming there are no spaces in the values you want to match, you could use:
ON REPLACE(t1.b, ' ', '') LIKE '%`[MID`]:' + t2.d + '`[%' ESCAPE '`'