Select email address only (SQL) - sql

i have column in a table (column name is “from”), looks like this
blabla#hotmail.com
frank ocean real frankocean#mail.com
ari#gold.com
frits west f.west#mail.com
I want to select the email addresses only, how do i do this? with a substring?
I can find a domain, but i want to have the complete mail addresses, like this:
blabla#hotmail.com
frankocean#mail.com
ari#gold.com
f.west#mail.com
thanks!

Reverse the string and look for a space before the address: try this
CREATE TABLE #Addresses (EmailAddress VARCHAR(100))
INSERT INTO #Addresses (EmailAddress)
SELECT 'blabla#hotmail.com'
UNION
SELECT 'frank ocean real frankocean#mail.com'
UNION
SELECT 'ari#gold.com'
UNION
SELECT 'frits west f.west#mail.com'
SELECT LTRIM(RTRIM(RIGHT(EmailAddress, CHARINDEX(' ', REVERSE(' ' + EmailAddress),CHARINDEX('#', REVERSE(' '+emailAddress)))))) FROM #Addresses
EDIT: if you have any strings that contain the name after the address, you can use the following to strip out the address:
CREATE TABLE #Addresses (EmailAddress VARCHAR(100))
INSERT INTO #Addresses (EmailAddress)
SELECT 'blabla#hotmail.com'
UNION
SELECT 'frank ocean real frankocean#mail.com'
UNION
SELECT 'ari#gold.com'
UNION
SELECT 'frits west f.west#mail.com'
UNION
SELECT 'me#me.com my name'
SELECT LTRIM(RTRIM(LEFT(RIGHT(EmailAddress, CHARINDEX(' ', REVERSE(' ' + EmailAddress),CHARINDEX('#', REVERSE(' '+emailAddress)))), CHARINDEX(' ', EmailAddress + ' '))) FROM #Addresses
DROP TABLE #Addresses
EDIT 2: forgot to add trimming functions
EDIT 3: final code using the OP's column name (table name not posted):
SELECT LTRIM(RTRIM(LEFT(RIGHT([From], CHARINDEX(' ', REVERSE(' ' + [From]),CHARINDEX('#', REVERSE(' '+[From])))), CHARINDEX(' ', [From]+ ' '))) FROM -- whatever your table is named

If the output is always in the format that you gave, then hopefully this will work:
SELECT RIGHT([From], CHARINDEX(' ', REVERSE(' ' + [From])) - 1) AS [Result]
FROM YourTable
This will only work if there is a space before the input that you want (the actual email address). I use this for a similar purpose in for some legacy dodgy customer data.
This is for SQL Server, I don't know if it will work for any other RDBMS.

Related

What MySQL LIKE wildcard should I use to return someone's name without their title/prefix name?

I want to return name of customers and order them, but their titles must be excluded in ordering.
SELECT name
FROM customers
WHERE name LIKE ...
ORDER BY name
I mean by 'their titles' is such as Dr., Sn., Lady, Sir, Mr., and Mrs.
Possible solution to your problem.
In Oracle:
regexp_replace(user_name, '^(MISS|MS\.|MS|MRS\.|MRS|MR\.|MR)\s*', '') as user_name
Also you can use REPLACE () function like:
REPLACE (user_name, 'MISS', '') as user_name
If you have a column structure like (mr | mrs | other) / space / username you can try this:
with users(user_name) as
(select 'mr user name1' from dual union all
select 'miss username2 ' from dual union all
select 'other username 3' from dual )
select substr(user_name,instr(user_name,' ')+1) real_username from users
Output:
REAL_USERNAME
----------------
username 1
username 2
username 3
In MSSQL:
DECLARE #str VARCHAR(500)='Mr Sam'
SELECT Title,
first_name,
Substring(NAME, CASE
WHEN Charindex(' ', NAME) = 0 THEN 1
ELSE Charindex(' ', NAME)
END, Len(NAME)) last_name
FROM (SELECT CASE
WHEN LEFT(#str, Charindex(' ', #str)) IN( 'Mr', 'Mrs', 'Miss' ) THEN LEFT(#str, Charindex(' ', #str))
ELSE ''
END AS Title,
CASE
WHEN LEFT(#str, Charindex(' ', #str)) IN ( 'Mr', 'Mrs', 'Miss' ) THEN LEFT(Stuff(#str, 1, Charindex(' ', #str), ''), Charindex(' ', Stuff(#str, 1, Charindex(' ', #str), '')))
ELSE LEFT(#str, Charindex(' ', #str))
END AS first_name,
CASE
WHEN LEFT(#str, Charindex(' ', #str)) IN ( 'Mr', 'Mrs', 'Miss' ) THEN Stuff(#str, 1, Charindex(' ', #str), '')
ELSE #str
END NAME) a
Technically using a % before their name will allow any prefix, which would get you the desired result (ex. WHERE name LIKE ('%' + #name). However, this is not the recommended approach on larger data sets as you will see significant performance issues with this approach.
You need to be more specific. First of all: Which SQL "flavor" are you using? Postgres? Oracle? MySql? This is very important because each engine has different functions. Every time you ask an SQL question in SO, be sure to include at the very least a tag mentioning which DBMS you're using.
Now, what do you mean by "I shouldn't return them". Do you mean you should not return records which have a prefix, or do you mean you need to return the records but without the prefix? (So if you have Dr. Henry Gutierrez, do you exclude him from the result? Or have it output as Henry Gutierrez?)
This is also a good place for another tip: Always write an expected output in your questions. "If X is Y then I expect the output to be this:"
If you need to exclude them entirely, you can use a REGEXP match (Once again, I cannot list a specific function because I have no idea which type of SQL you're using) Something like WHERE REGEXP(UPPER(COL)) NOT ('^(MS|MR)\s+.*$')
If it's the 2nd case, that's going to be much harder because you'd need to get a substring which excludes the prefix, but the prefixes all have different sizes so you can't just write a "one size fits all"
In general, it's a bad normalization practice to have prefixes in your SQL database. You should have a column called PREFIX and another column for the name itself.
EDIT: Based on your answer. This is the closest you can get to achieving what you want.
SELECT NAME
FROM (SELECT NAME,
CASE WHEN NAME LIKE 'MR %' THEN SUBSTRING(NAME, 4)
WHEN NAME LIKE 'MRS %' THEN SUBSTRING(NAME, 5)
ELSE NAME AS NAME2
FROM YOUR_TABLE ORDER BY NAME2) AS SUBQ
I am 99% sure this will not return the results ordered though, because the select order might be ignored outside of the subquery, so you can also just try whats in the subquery in a main query instead, but this will output 2 columns.
***My reply is in pseudocode. It is not exactly MySql syntax, you will need to check MySql documentation for the actual substring function implementation it has and for the CASE syntax.

Incorporate case statement in where clause

My requirement is as follows: I need to extract all companies data, which has similar name in table (first 3 words should occur in the name,can be in middle) as the input company name.
My query is working fine for data where name has more than 3 words ,but for less or equal to 3 it's failing.
I didn't get how to incorporate conditions in where clause.
My query is as below
select regno,name from ereg
where
(name like '%' +(
SELECT SUBSTRING(name, 0, CHARINDEX(' ', name, CHARINDEX(' ', name, CHARINDEX(' ', name, 0)+1)+1)) matchingwrd
FROM ereg where regno='C2113-UPD01')+'%')
script is as below
CREATE TABLE ereg(
regnoINT, name VARCHAR(50)
);
INSERT INTO ereg (regno,name)
values
('C2113-UPD01','future company Ltd'),
('C2223-UPD01','MY future company Ltd Corp'),
('C2113-UPD01','Prime Private Furnishings housing Ltd '),
('C26903-UPD01','My Prime Private Furnishings Service '),
for example,its working fine for regno='C2113-UPD01' and gives output -->>'C26903-UPD01','My Prime Private Furnishings Service
but if input is 'C2113-UPD01' My query fails and not able to fetch 'C2223-UPD01' company data
Your table data insert script, the data and the script all seems to be not taken from a working version. I had to clean everything.
What I did to get the 3 words is adding another space in front of the name:
Still your query gave me trouble. But here is how I did that
;With cted as
(
Select regno, name,
SUBSTRING(name + ' ', 0, CHARINDEX(' ', name + ' ', CHARINDEX(' ', name + ' ', CHARINDEX(' ', name + ' ', 0)+1)+1)) as ThreeWords
from ereg
)
Select c1.regno, c1.name, c2.regno, c2.name
from cted c1
inner join cted c2 on c2.name like '%' + c1.ThreeWords + '%' and c1.regno <> c2.regno
Where c1.regno='C2213-UPD01' -- or c1.regno='C2113-UPD01'
Here is the fiddle

deleting second comma in data

Ok so I have a table called PEOPLE that has a name column. In the name column is a name, but its totally a mess. For some reason its not listed such as last, first middle. It's sitting like last,first,middle and last first (and middle if there) are separated by a comma.. two commas if the person has a middle name.
example:
smith,steve
smith,steve,j
smith,ryan,tom
I'd like the second comma taken away (for parsing reason ) spaces put after existing first comma so the above would come out looking like:
smith, steve
smith, steve j
smith, ryan tom
Ultimately I'd like to be able to parse the names into first, middle, and last name fields, but that's for another post :_0. I appreciate any help.
thank you.
Drop table T1;
Create table T1(Name varchar(100));
Insert T1 Values
('smith,steve'),
('smith,steve,j'),
('smith,ryan,tom');
UPDATE T1
SET Name=
CASE CHARINDEX(',',name, CHARINDEX(',',name)+1) WHEN
0 THEN Name
ELSE
LEFT(name,CHARINDEX(',',name, CHARINDEX(',',name)+1)-1)+' ' +
RIGHT(name,LEN(Name)-CHARINDEX(',',name, CHARINDEX(',',name)+1))
END
Select * from T1
This seems to work. Not the most concise but avoids cursors.
DECLARE #people TABLE (name varchar(50))
INSERT INTO #people
SELECT 'smith,steve'
UNION
SELECT 'smith,steve,j'
UNION
SELECT 'smith,ryan,tom'
UNION
SELECT 'commaless'
SELECT name,
CASE
WHEN CHARINDEX(',',name) > 0 THEN
CASE
WHEN CHARINDEX(',',name,CHARINDEX(',',name) + 1) > 0 THEN
STUFF(STUFF(name, CHARINDEX(',',name,CHARINDEX(',',name) + 1), 1, ' '),CHARINDEX(',',name),1,', ')
ELSE
STUFF(name,CHARINDEX(',',name),1,', ')
END
ELSE name
END AS name2
FROM #people
Using a table function to split apart the names with a delimiter and for XML Path to stitch them back together, we can get what you're looking for! Hope this helps!
Declare #People table(FullName varchar(200))
Insert Into #People Values ('smith,steve')
Insert Into #People Values ('smith,steve,j')
Insert Into #People Values ('smith,ryan,tom')
Insert Into #People Values ('smith,john,joseph Jr')
Select p.*,stuff(fn.FullName,1,2,'') as ModifiedFullName
From #People p
Cross Apply (
select
Case When np.posID<=2 Then ', ' Else ' ' End+np.Val
From #People n
Cross Apply Custom.SplitValues(n.FullName,',') np
Where n.FullName=p.FullName
For XML Path('')
) fn(FullName)
Output:
ModifiedFullName
smith, steve
smith, steve j
smith, ryan tom
smith, john joseph Jr
SplitValues table function definition:
/*
This Function takes a delimited list of values and returns a table containing
each individual value and its position.
*/
CREATE FUNCTION [Custom].[SplitValues]
(
#List varchar(max)
, #Delimiter varchar(1)
)
RETURNS
#ValuesTable table
(
posID int
,val varchar(1000)
)
AS
BEGIN
WITH Cte AS
(
SELECT CAST('<v>' + REPLACE(#List, #Delimiter, '</v><v>') + '</v>' AS XML) AS val
)
INSERT #ValuesTable (posID,val)
SELECT row_number() over(Order By x) as posID, RTRIM(LTRIM(Split.x.value('.', 'VARCHAR(1000)'))) AS val
FROM Cte
CROSS APPLY val.nodes('/v') Split(x)
RETURN
END
GO
String manipulation in SQLServer, outside of writing your own User Defined Function, is limited but you can use the PARSENAME function for your purposes here. It takes a string, splits it on the period character, and returns the segment you specify.
Try this:
DECLARE #name VARCHAR(100) = 'smith,ryan,tom'
SELECT REVERSE(PARSENAME(REPLACE(REVERSE(#name), ',', '.'), 1)) + ', ' +
REVERSE(PARSENAME(REPLACE(REVERSE(#name), ',', '.'), 2)) +
COALESCE(' ' + REVERSE(PARSENAME(REPLACE(REVERSE(#name), ',', '.'), 3)), '')
Result: smith, ryan tom
If you set #name to 'smith,steve' instead, you'll get:
Result: smith, steve
Segment 1 actually gives you the last segment, segment 2 the second to last etc. Hence I've used REVERSE to get the order you want. In the case of 'steve,smith', segment 3 will be null, hence the COALESCE to add an empty string if that is the case. The REPLACE of course changes the commas to periods so that the split will work.
Note that this is a bit of a hack. PARSENAME will not work if there are more than four parts and this will fail if the name happens to contain a period. However if your data conforms to these limitations, hopefully it provides you with a solution.
Caveat: it sounds like your data may be inconsistently formatted. In that case, applying any automated treatment to it is going to be risky. However, you could try:
UPDATE people SET name = REPLACE(name, ',', ' ')
UPDATE people SET name = LEFT(name, CHARINDEX(' ', name)-1)+ ', '
+ RIGHT(name, LEN(name) - CHARINDEX(' ', name)
That'll work for the three examples you give. What it will do to the rest of your set is another question.
Here's an example with CHARINDEX() and SUBSTRING
WITH yourTable
AS
(
SELECT names
FROM
(
VALUES ('smith,steve'),('smith,steve,j'),('smith,ryan,tom')
) A(names)
)
SELECT names AS old,
CASE
WHEN comma > 0
THEN SUBSTRING(spaced_names,0,comma + 1) --before the comma
+ SUBSTRING(spaced_names,comma + 2,1000) --after the comma
ELSE spaced_names
END AS new
FROM yourTable
CROSS APPLY(SELECT CHARINDEX(',',names,CHARINDEX(',',names) + 1),REPLACE(names,',',', ')) AS CA(comma,spaced_names)

How to find more than 1 uppercase character

I'm running a series of SQL queries to find data that needs cleaning up. One of them I want to do is look for:
2 or more uppercase letters in a row
starting with a lowercase letter
space then a lowercase letter
For example my name should be "John Doe". I would want it to find "JOhn Doe" or "JOHN DOE" or "John doe", but I would not want it to find "John Doe" since that is formatted correctly.
I am using SQL Server 2008.
The key is to use a case-sensitive collation, i.e. Latin1_General_BIN*. You can then use a query with a LIKE expression like the following (SQL Fiddle demo):
select *
from foo
where name like '%[A-Z][A-Z]%' collate Latin1_General_BIN --two uppercase in a row
or name like '% [a-z]%' collate Latin1_General_BIN --space then lowercase
*As per How do I perform a case-sensitive search using LIKE?, apparently there is a "bug" in the Latin1_General_CS_AS collation where ranges like [A-Z] fail to be case sensitive. The solution is to use Latin1_General_BIN.
First, I think you should make a function that returns a proper name (sounds like you need one anyway). See here under the heading "Proper Casing a Persons Name". Then find the ones that don't match.
SELECT Id, Name, dbo.ProperCase(Name)
FROM MyTable
WHERE Name <> dbo.PoperCase(Name) collate Latin1_General_BIN
This will help you clean up the data and tweak the function to what you need.
You can use a regular expression. I'm not a SQL Server whiz, but you want to use RegexMatch. Something like this:
select columnName
from tableName
where dbo.RegexMatch( columnName,
N'[A-Z]\W[A-Z]' ) = 1
If your goal is to update your column to capitalize the first character of each word (in your case firstName and lastName) , you can use the following query.
Create a sample table with data
Declare #t table (Id int IDENTITY(1,1),Name varchar(50))
insert into #t (name)values ('john doe'),('lohn foe'),('tohnytty noe'),('gohnsdf fgedsfsdf')
Update query
UPDATE #t
SET name = UPPER(LEFT(SUBSTRING(Name, 1, CHARINDEX(' ', Name) - 1), 1)) + RIGHT(SUBSTRING(Name, 1, CHARINDEX(' ', Name) - 1), LEN(SUBSTRING(Name, 1, CHARINDEX(' ', Name) - 1)) - 1) +
' ' +
UPPER(LEFT(SUBSTRING(Name, CHARINDEX(' ', Name) + 1, 8000), 1)) + RIGHT(SUBSTRING(Name, CHARINDEX(' ', Name) + 1, 8000), LEN(SUBSTRING(Name, CHARINDEX(' ', Name) + 1, 8000)) - 1)
FROM #t
Output
SELECT * FROM #t
Id Name
1 John Doe
2 Lohn Foe
3 Tohnytty Noe
4 Gohnsdf Fgedsfsdf
I use this way:
;WITH yourTable AS(
SELECT 'John Doe' As name
UNION ALL SELECT 'JOhn Doe'
UNION ALL SELECT 'JOHN DOE'
UNION ALL SELECT 'John doe'
UNION ALL SELECT 'John DoE'
UNION ALL SELECT 'john Doe'
UNION ALL SELECT 'jOhn dOe'
UNION ALL SELECT 'jOHN dOE'
UNION ALL SELECT 'john doe'
)
SELECT name
FROM (
SELECT name,
LOWER(PARSENAME(REPLACE(name, ' ', '.'), 1)) part2,
LOWER(PARSENAME(REPLACE(name, ' ', '.'), 2)) part1
FROM yourTable) t
WHERE name COLLATE Latin1_General_BIN = UPPER(LEFT(part1,1)) + RIGHT(part1, LEN(part1) -1) +
' ' + UPPER(LEFT(part2,1)) + RIGHT(part2, LEN(part2) -1)
Note:
This will be good for just two parted names for more, it should improved.

eliminate first numeric from string

I have the data in column like this 12 address, i want to eliminate numeric with address how can i do to achieve the result Address. Here can be any other string also not only address.
Query:
SELECT Address FROM TABLE
Thanks
In SQL Server:
SELECT
COALESCE(LTRIM(SUBSTRING(Address, FirstPos, 2147483647)), '') AS Address
FROM (
SELECT
Address,
NULLIF(PATINDEX('%[^0-9]%', Address), 0) AS FirstPos
FROM atable
) s
SELECT SUBSTRING(address, CHARINDEX(' ',address)+1,field_len)
FROM table
Explained
Syntax: SUBSTRING(fieldname, start_position, end_position)
In your case
SUBSTRING(
address -- your field name
, CHARINDEX(' ',address)+1 -- find the space char
, field_len -- get all the rest of the string
)
SELECT RIGHT(Address,LEN(Address) - CHARINDEX (' ', Address) + 1) FROM tbl
Something like this should work.