SQL to find string in select - sql

I have a select statement like this:
SELECT ColumnA,
CASE ColumnB = 'England' THEN ...
In the part after the THEN statement, i want to take the numbers from ColumnC,
e.g. ColumnC value = ABC 123 DEF, and i need the '123' part.
Does anyone know the sql code i can use to do this within the select when the '123' will always be in between the only 2 spaces in the string? (MS SQL)

The main key is that you need to use ColumnC LIKE '% % %' so that it does not fail when the data does not contain two spaces.
If your numbers are going to be less than 20-char long, you can use this
SELECT ColumnA,
CASE WHEN ColumnB = 'England' AND ColumnC LIKE '% % %' THEN
RTRIM(LEFT(REPLACE(STUFF(columnc, 1, PatIndex('% %', columnc), ''), ' ', REPLICATE(' ', 20)),20))
ELSE ....
Or you can use this
SELECT ColumnA,
CASE WHEN ColumnB = 'England' AND ColumnC LIKE '% % %' THEN
SUBSTRING(
SUBSTRING(
ColumnC,
1,
CHARINDEX(' ',ColumnC,CHARINDEX(' ', ColumnC)+1)-1),
1+CHARINDEX(' ', ColumnC),
LEN(ColumnC))
ELSE ....

You can use a combination of CHARINDEX and SUBSTRING:
DECLARE #Test TABLE(ColumnC varchar(100))
INSERT #Test
VALUES ('ABC 123 DEF')
SELECT SUBSTRING(ColumnC,
CHARINDEX(' ', ColumnC) + 1, -- first space
CHARINDEX(' ', ColumnC, CHARINDEX(' ', ColumnC) + 1)
- CHARINDEX(' ', ColumnC)) -- length from first to second space
FROM #Test
This works as expected for the sample string provided.

SUBSTRING_INDEX(SUBSTRING_INDEX( ColumnC , ' ', 2 ),' ',-1)

Related

How can I CONCAT portions of three columns to one new column

I am trying to create a new column in my results that is made up on the first 3 characters of "PrimaryName", all of "VendorCity", and the first 5 characters of "VendorZip"
SELECT,VendorName
,replace(PrimaryVendorLocationName,' ','') as PrimaryName
,replace(PrimaryVendorLocationCity,' ','') as VendorCity
,replace(PrimaryVendorLocationZipCode,' ','') as VendorZip
FROM [table]
As you can see I also need to remove spaces to ensure a cleaner return. I would like to call the new column "NewVendorCode". So a record that originates like this:
R A Slack
Chicago Heights
60654-1234
Will return this:
RASChicagoHeights60654
You can use the following, using LEFT (MySQL / TSQL):
SELECT CONCAT(
LEFT(REPLACE(PrimaryVendorLocationName, ' ', ''), 3),
REPLACE(PrimaryVendorLocationCity, ' ', ''),
LEFT(REPLACE(PrimaryVendorLocationZipCode, ' ', ''), 5)
) FROM table_name
... or you can use SUBSTRING (MySQL / TSQL) (instead of LEFT):
SELECT CONCAT(
SUBSTRING(REPLACE(PrimaryVendorLocationName, ' ', ''), 1, 3),
REPLACE(PrimaryVendorLocationCity, ' ', ''),
SUBSTRING(REPLACE(PrimaryVendorLocationZipCode, ' ', ''), 1, 5)
) FROM table_name
Note: As you can see the SELECT querys work on MySQL and TSQL without change.
demo (MySQL): https://www.db-fiddle.com/f/wTuKzosFgkEuKXtruCTCxg/0
demo (TSQL): http://sqlfiddle.com/#!18/dbc98/1/1
You can use the following code:
SELECT VendorName+
replace(PrimaryVendorLocationName,' ','') +
replace(PrimaryVendorLocationCity,' ','') +
replace(PrimaryVendorLocationZipCode,' ','') as NewVendorCode
SELECT VendorName
,PrimaryName
,VendorCity
,VendorZip
,CONCAT(LEFT(PrimaryName,3),VendorCity,LEFT(VendorZip,5)) As NewVendorCode
FROM (
SELECT VendorName
,replace(PrimaryVendorLocationName,' ','') as PrimaryName
,replace(PrimaryVendorLocationCity,' ','') as VendorCity
,replace(PrimaryVendorLocationZipCode,' ','') as VendorZip
FROM [table]
)

Extract forename if the character is more then 2 letter

I have to get the forename from the c.forename if c.known_as column is null or blank.
This i achieved with case when statement using
CASE
WHEN IND.KNOWN_AS IS NULL OR ind.KNOWN_AS=''
THEN ind.FORENAMES
ELSE ind.KNOWN_AS
END AS 'Known As'
My issue is in the forename column i have name like Jhon Smith where i would like to extract only John, below is an example what i want to achieve
Desire output c.forename
John Mr John
Jhon Jhon Smith
blank Jo
blank J
So , basically it will only take forname skipping 'Mr', 2nd it should take only forename which has more than 2 character.
My current query is:
Select ind.FORENAMES,
ind.KNOWN_AS,
case when (known_as is null or known_as = '' ) and charindex(' ', forenames) > 2
then substring(forenames, 1, charindex(' ', forenames) - 1) end as FORENAMES2,
output
from individual ind
join member m on m.individual_ref=ind.individual_ref
and m.MEMBERSHIP_NO in ('001','002','003','004','005','006','007')
where m.member_status=33
You could use following case when statement to verify your conditions:
For SQL Server:
case when (c.known_as is null or c.known_as = '' )
and charindex(' ', c.forename) > 3 then substring(c.forename, 1, charindex(' ', c.forename) - 1) end
For MySQL:
case when (c.known_as is null or c.known_as = '' )
and locate(' ', c.forename) > 3 then substring(c.forename, 1, locate(' ', c.forename) - 1) end
Little explanation: if the first name must be longer than 2 characters, that means that first space must occur at least at index 4. And that what the condition is about: locate(' ', c.forename) > 3 or substring(' ', c.forename) > 3
NOTE
You have to first strip down all occurences of Mr, Mrs, Ms in c.forename column, like this (syntax for MySQL and SQL Server):
replace(replace(replace(c.forename, 'Mrs ', ''), 'Mr ', ''), 'Ms ', '')
You have to include it in your query lke this:
Select FORENAMES,
KNOWN_AS,
case when (known_as is null or known_as = '' ) and charindex(' ', FORENAMES2) > 2
then substring(FORENAMES2, 1, charindex(' ', FORENAMES2) - 1) end as FORENAMES2,
output
from (
Select ind.FORENAMES,
ind.KNOWN_AS,
replace(replace(replace(ind.FORENAMES, 'Mrs ', ''), 'Mr ', ''), 'Ms ', '') FORENAMES2,
output
from individual ind
join member m on m.individual_ref = ind.individual_ref
where m.member_status=33
and m.MEMBERSHIP_NO in ('001','002','003','004','005','006','007')
)
Try this:
DECLARE #DataSource TABLE
(
[name] VARCHAR(32)
);
INSERT INTO #DataSource ([name])
VALUES (' Mr John ')
,('Jhon Smith')
,(' Jo ')
,(' J ');
WITH SanitizeDataSoruce ([name], [name_reversed]) AS
(
SELECT LTRIM(RTRIM([name]))
,REVERSE(LTRIM(RTRIM([name])))
FROM #DataSource
)
SELECT [name]
,CASE
WHEN CHARINDEX(' ', [name]) > 1 THEN REVERSE(SUBSTRING([name_reversed], 0, CHARINDEX(' ', [name_reversed])))
ELSE ''
END
FROM SanitizeDataSoruce;

SQL - re.split: BY comma THEN space

I want to split the following string into City, Province, Postal Code.
Thank you so much for the help!!!!
Description: Split by comma, then split by space only once.
A = 'Vaughan, ON L6D 9X0'
Result:
(Vaughan, ON, L6D9X0)
Attempt:
re.split(',|/s[1]', A)
Try This,
This selected the values into rows, maybe you can pivot the cte C2 same in order to get it as columns
WITH CTE
AS
(
SELECT
1 Seq,
'Vaughan, ON L6D 9X0' "Txt"
UNION ALL
SELECT
Seq+1 "Seq",
Txt = CASE WHEN Txt LIKE '% %'
THEN LTRIM(RTRIM(SUBSTRING(Txt,CHARINDEX(' ',Txt),LEN(Txt))))
ELSE NULL END
FROM CTE
WHERE ISNULL(txt,'')<>''
),C2
AS
(
SELECT
CASE Seq
WHEN 1 THEN 'City'
WHEN 2 THEN 'Province'
ELSE 'PostalCode' END "Head",
CASE Seq
WHEN 1
THEN SUBSTRING(Txt,1,CHARINDEX(',',Txt)-1)
WHEN 2
THEN SUBSTRING(Txt,1,CHARINDEX(' ',Txt)-1)
ELSE Txt END "Txt"
FROM CTE
WHERE Seq<4
)
SELECT
*
FROM C2;
If you have multiple rows that need to be parsed in the same way then, you can give the same in the select statement of 1st CTE and in that case, the logic for Seq on the first select might need to be changed. As per the above, the output will be as follows
With Postgres you can do that using:
select split_part(a, ',', 1) as city,
left(trim(split_part(a,',',2)), strpos(trim(split_part(a,',',2)), ' ')),
substr(trim(split_part(a,',',2)) as province, strpos(trim(split_part(a,',',2)), ' ') + 1) as postal_code
from the_table;
This can be made a bit more readable by using a derived table:
select city,
left(second_part, strpos(second_part, ' ')) as province,
substr(second_part, strpos(second_part, ' ') + 1) as postal_code
from (
select split_part(a, ',', 1) as city,
trim(split_part(a, ',', 2)) as second_part
from the_table
) t
IF, You are working with Microsoft SQL Server, then you could use SUBSTRING() &CHARINDEX() function to find specific Char index to split the string values.
SELECT SUBSTRING(<column>, 1, CHARINDEX(',', <column>)-1) City,
SUBSTRING(SUBSTRING(<column>, CHARINDEX(' ', <column>)+1, LEN(<column>)), 1, CHARINDEX(' ', SUBSTRING(<column>, CHARINDEX(' ', <column>)+1, LEN(<column>)))) Province,
SUBSTRING(SUBSTRING(<column>, CHARINDEX(' ', <column>)+1, LEN(<column>)), CHARINDEX(' ', SUBSTRING(<column>, CHARINDEX(' ', <column>)+1, LEN(<column>)))+1, LEN(<column>)) [Postal Code];
Desired Output :
City Province Postal Code
Vaughan ON L6D 9X0

Extracting first word from a string in SQL, where the string is a single word

I am able to extract the first word from a string, using ANSI SQL, like this:
SELECT SUBSTRING(name FROM 1 FOR POSITION(' ' IN name)) AS first_name
However, if the original string is only one word long (ie, if there is no space), it returns an empty substring.
How can the above query be adapted to solve this problem?
Thanks in advance.
I'm sure there is a cleaner way to do it, but this works.
DECLARE #tbl TABLE (i varchar(100));
INSERT INTO #tbl ( i )
VALUES ('hello'), ('hello space here');
SELECT *,
SUBSTRING(i, 0, CASE CHARINDEX(' ', i)
WHEN 0 THEN LEN(i) + 1
ELSE CHARINDEX(' ', i)
END)
FROM #tbl
Simply but messy solution - add a space on the end:
SELECT SUBSTRING((name || ' ') FROM 1 FOR POSITION(' ' IN (name || ' '))) AS first_name
Use a conditional if statement.
For a MySQL/SQL Server answer:
SELECT IF(INSTR(name, ' ') >0, LEFT(name, INSTR(name, ' ') - 1), name) AS firstname
For Oracle:
SELECT IF(INSTRB(name, ' ', 1, 1) >0, SUBSTR(name, 1, INSTRB(name, ' ', 1, 1) - 1), name) AS firstname
I personally prefer the Regexp query for this, but below query also works.
You basically append a space at the end of the string and search for the position of the space using INSTR.
ORACLE:
select substr(Var1, 0,INSTR(Var1||' ',' ')) from table-name;
Replace Var1 with the column-name or string you are evaluating.
Put Column Name in place of #foo
DECLARE #Foo VARCHAR(50) = 'One Two Three'
SELECT
CASE
--For One Word
WHEN CHARINDEX(' ', #Foo, 1) = 0 THEN #Foo
--For multi word
ELSE SUBSTRING(#Foo, 1, CHARINDEX(' ', #Foo, 1) - 1)
END
DECLARE #test VARCHAR(50) = 'One Two Three'
SELECT SUBSTRING(LTRIM(#test),1,(CHARINDEX(' ',LTRIM(#test) + ' ')-1))
you can use this to get the first word of a string.initcap
will get you the first letter capital.
SELECT SUBSTR(column_1, 1, INSTR(column_1, ' ', 1,1) ) FROM table_name WHERE column_1= initcap('your string');

How to combine SQL queries for same column?

I have searched but not found any examples for my particular problem.
I am trying to strip some unwanted text from a column containing department names. I am trying to combine 2 queries to do this.
This first query strips all characters after the colon in the name:
SELECT
CASE WHEN CHARINDEX(':', DB.Table.DEPT)>0
THEN
LEFT(DB.Table.DEPT, CHARINDEX(':', DB.Table.DEPT)-1)
ELSE
DB.Table.DEPT
END
FROM
DB.Table
The second query strips the prefix from the name:
SELECT
REPLACE(
REPLACE(
REPLACE (DB.Table.DEPT,'[NA1] ','')
,'[NA2] ', '')
,'[NA3] ', '')
FROM
DB.Table
Both of these work great independent of each other, but when I try to combine them it fails.
SELECT
CASE WHEN CHARINDEX(':', DB.Table.DEPT)>0
THEN
LEFT(DB.Table.DEPT, CHARINDEX(':', DB.Table.DEPT)-1)
ELSE
DB.Table.DEPT
END
FROM
(SELECT
REPLACE(
REPLACE(
REPLACE (DB.Table.DEPT,'[NA1] ','')
,'[NA2] ', '')
,'[NA3] ', '')
FROM
DB.Table)
I could really use some guidance with this.
Thanks in advance.
Your query is syntactically incorrect, because you need an alias for the subquery and for the expression result:
SELECT (CASE WHEN CHARINDEX(':', DEPT)>0
THEN LEFT(DEPT, CHARINDEX(':', DEPT)-1)
ELSE DEPT
END)
FROM (SELECT REPLACE(REPLACE(REPLACE(t.DEPT,'[NA1] ',''
), '[NA2] ', ''
), '[NA3] ', ''
) as DEPT
FROM DB.Table t
) t;
EDIT:
To see both the original and new department:
SELECT (CASE WHEN CHARINDEX(':', new_DEPT) > 0
THEN LEFT(new_DEPT, CHARINDEX(':', newj_DEPT)-1)
ELSE new_DEPT
END),
Orig_DEPT
FROM (SELECT REPLACE(REPLACE(REPLACE(t.DEPT,'[NA1] ',''
), '[NA2] ', ''
), '[NA3] ', ''
) as new_DEPT,
t.DEPT as orig_DEPT
FROM DB.Table t
) t
You should always name your subquerys.
Try this:
SELECT
CASE WHEN CHARINDEX(':', x.DEPT)>0
THEN
LEFT(x.DEPT, CHARINDEX(':', x.DEPT)-1)
ELSE
x.DEPT
END AS DEPT
FROM
(
SELECT
REPLACE(REPLACE(REPLACE (DEPT,'[NA1] ','') ,'[NA2] ', ''),'[NA3] ', '') AS DEPT
FROM
DB.Table
) x