How to select domain name from email address
Using SUBSTRING_INDEX for "splitting" at '@' and '.' does the trick. See documentation at http://dev.mysql.com/doc/refman/5.1/de/string-functions.html#idm47531853671216.
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(email, '@', -1), '.', 1);
Example:
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX("[email protected]", '@', -1), '.', 1);
will give you "bar".
Here is what happens:
* Split "[email protected]" at '@'. --> ["foo", "bar.buz"]
* Pick first element from right (index -1). --> "bar.buz"
* Split "bar.buz" at '.' --> ["bar", "buz"]
* Pick first element (index 1) --> "bar"
Result: "bar"
If you also need to get rid of subdomains, use:
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX(email, '@', -1), '.', -2), '.', 1);
Example:
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX("[email protected]", '@', -1), '.', -2), '.', 1);
will give you "bar".
Assuming that the domain is a single word domain like gmail.com, yahoo.com, use
select (SUBSTRING_INDEX(SUBSTR(email, INSTR(email, '@') + 1),'.',1))
The inner SUBSTR
gets the right part of the email address after @
and the outer SUBSTRING_INDEX
will cut off the result at the first period.
otherwise if domain is expected to contain multiple words like mail.yahoo.com
, etc, use:
select (SUBSTR(email, INSTR(email, '@') + 1, LENGTH(email) - (INSTR(email, '@') + 1) - LENGTH(SUBSTRING_INDEX(email,'.',-1))))
LENGTH(email) - (INSTR(email, '@') + 1) - LENGTH(SUBSTRING_INDEX(email,'.',-1))
will get the length of the domain minus the TLD (.com, .biz etc. part)
by using SUBSTRING_INDEX
with a negative count which will calculate from right to left.
I prefer:
select right(email_address, length(email_address)-INSTR(email_address, '@')) ...
so you don't have to guess how many sub-domains your user's email domain has.
For PostgreSQL:
split_part(email, '@', 2) AS domain
Full query:
SELECT email, split_part(email, '@', 2) AS domain
FROM users;
Ref: http://www.postgresql.org/docs/current/static/functions-string.html
Credit to https://stackoverflow.com/a/19230892/1048433