8

Mail data:

Mailid
-------------------------------
venkattaramanan1985@gmail.com
madanraj@gmail.com

Expected output

Name                 DomainName  Extension
-------------------  ----------  ---------
venkattaramanan1985  gmail       com
madanraj             gmail       com
shA.t
  • 16,580
  • 5
  • 54
  • 111
vinay s
  • 81
  • 1
  • 1
  • 2
  • Hello, below query works if the name doesn.t have special characters – vinay s Feb 20 '14 at 05:40
  • select SUBSTRING(mailid,(CHARINDEX('@',mailid)-100),100)as Name ,SUBSTRING(mailid, (CHARINDEX('@',mailid)+1), CHARINDEX('.',mailid) - (CHARINDEX('@', mailid)+2) + Len('.'))as DomainName ,SUBSTRING(mailid,(CHARINDEX('.',mailid)+1),100)as Extension FROM Mail; – vinay s Feb 20 '14 at 05:40
  • what if name has special characters the above query will fail? – vinay s Feb 20 '14 at 05:41
  • If your problem solved with at least one of these answers, please accept one of them as an answer. – QMaster Oct 21 '18 at 09:05

4 Answers4

19

It has a simple one line solution, Assume email address is admin@system.org, below query will return parts as mentioned:

SELECT 
--admin
LEFT(emailAddres, CHARINDEX('@', emailAddres) - 1) AS accountName  

--system.org
RIGHT(emailAddres, LEN(emailAddres) - CHARINDEX('@', emailAddres)) AS domainWithExtension

--system
LEFT(RIGHT(emailAddres, LEN(emailAddres) - CHARINDEX('@', emailAddres)), CHARINDEX('.', RIGHT(emailAddres, LEN(emailAddres) - CHARINDEX('@', emailAddres))) - 1) AS domain

--org
RIGHT(RIGHT(emailAddres, LEN(emailAddres) - CHARINDEX('@', emailAddres)), LEN(RIGHT(emailAddres, LEN(emailAddres) - CHARINDEX('@', emailAddres))) - CHARINDEX('.', RIGHT(emailAddres, LEN(emailAddres) - CHARINDEX('@', emailAddres)))) AS extension

Hope this help.

QMaster
  • 3,743
  • 3
  • 43
  • 56
5

First of all, why use the SQL server for that?

I recommend to use the client for the string manipulation and just let the SQL server return the data. That should be the only job for the SQL server for your case.

If you really have to use the SQL server for that you may want to read how to split strings in SQL beforehand. (for performance comparison read here)

For the following proposed solution you need a table-value-function to split a passed string with a specified delimiter which returns the ordered substrings. I modified the Common Table Expression taken from here to return the ordering as well.

CREATE FUNCTION dbo.SplitStrings_CTE
(
   @List       NVARCHAR(MAX),
   @Delimiter  NVARCHAR(255)
)
RETURNS @Items TABLE ([Order] INT IDENTITY(1,1) NOT NULL, [Item] NVARCHAR(4000))
WITH SCHEMABINDING
AS
BEGIN
    --same as the original here, the ordering is inserted automatically by IDENTITY
    (...)
END

Now I added a function to split an email string re-using the function above:

CREATE FUNCTION dbo.SplitEmail
(
   @email NVARCHAR(254)
)
RETURNS @splitted TABLE (
    [Email] NVARCHAR(254),
    [Name] NVARCHAR(254),
    [DomainName] NVARCHAR(254),
    [Extension] NVARCHAR(254)
)
WITH SCHEMABINDING
AS
BEGIN
    DECLARE @name NVARCHAR(254), @domain NVARCHAR(254), @ext NVARCHAR(254)
    --init the email parts with defaults
    SELECT @name = ISNULL(@email, ''), @domain = '', @ext = '';
    --we only want to split @email if at least one '@' is found in it
    IF (@email IS NOT NULL AND LEN(@email) <> 0 AND CHARINDEX('@', @email) <> 0) BEGIN
        --take the last occuring substring from @email as the @domain
        SELECT TOP 1 @domain = [Item]
        FROM [dbo].[SplitStrings_CTE](@name, '@')
        ORDER BY [Order] DESC
        --@email without @domain + '@' is the @name
        SET @name = LEFT(@name, LEN(@name) - LEN(@domain) - 1)
        --we only want to split @domain if at least one '.' is found in it
        IF (CHARINDEX('.', @domain) <> 0) BEGIN
            --take the last occuring substring from @domain as the @ext
            SELECT TOP 1 @ext = [Item]
            FROM [dbo].[SplitStrings_CTE](@domain, '.')
            ORDER BY [Order] DESC
            --split the @ext from the @domain
            SET @domain = LEFT(@domain, LEN(@domain) - LEN(@ext) - 1)
        END
        ELSE BEGIN
            SET @ext = @domain
            SET @domain = ''
        END
    END
    INSERT INTO @splitted ([Email], [Name], [DomainName], [Extension])
    VALUES (@email, @name, @domain, @ext)
    RETURN
END

Calling the function - for example:

DECLARE @@samples TABLE([mailid] NVARCHAR(255))

INSERT INTO @@samples ([mailid]) VALUES ('venkattaramanan1985@gmail.com')
INSERT INTO @@samples ([mailid]) VALUES ('madanraj@gmail.com')
INSERT INTO @@samples ([mailid]) VALUES ('madanraj@sub.gmail.com')
INSERT INTO @@samples ([mailid]) VALUES ('sm@al.l')
INSERT INTO @@samples ([mailid]) VALUES ('is@sane.')
INSERT INTO @@samples ([mailid]) VALUES ('is@sane')
INSERT INTO @@samples ([mailid]) VALUES ('rubbish@h.h.h.h.h')
INSERT INTO @@samples ([mailid]) VALUES (NULL)
INSERT INTO @@samples ([mailid]) VALUES ('')
INSERT INTO @@samples ([mailid]) VALUES ('invalid')
INSERT INTO @@samples ([mailid]) VALUES ('@@@@@@@@@...')

SELECT e.*
FROM @@samples AS s
CROSS APPLY dbo.SplitEmail(s.mailid) AS e

will return this result:

Email                              Name                    DomainName        Extension
---------------------------------  ----------------------  ----------------  ------------
venkattaramanan1985@gmail.com      venkattaramanan1985     gmail             com
madanraj@gmail.com                 madanraj                gmail             com
madanraj@sub.gmail.com             madanraj                sub.gmail         com
sm@al.l                            sm                      al                l
is@sane.                           is                                        sane
is@sane                            is                                        sane
rubbish@h.h.h.h.h                  rubbish                 h.h.h.h           h
NULL                                                                         

invalid                            invalid                                   
@@@@@@@@@...                       @@@@@@@@                ..                
Community
  • 1
  • 1
ckerth
  • 316
  • 1
  • 9
2
declare @var varchar(50) ='Abc.xyz@rediffmail.com';
select 
SUBSTRING(@var,0,charindex('@',@var)) as UserName
,
Substring(@var,charindex('@',@var)+1,charindex('.',@var,charindex('@',@var,0))-(charindex('@',@var)+1)) as DomainName
,
substring(@var,charindex('.',@var,charindex('@',@var))+1,len(@var)) as Ext
rollstuhlfahrer
  • 3,988
  • 9
  • 25
  • 38
Amardeep
  • 21
  • 1
  • While this code may answer the question, providing additional context regarding why and/or how this code answers the question improves its long-term value. – rollstuhlfahrer Apr 05 '18 at 06:37
  • declare @var varchar(50) ='venkattaramanan1985@gmail.com'; select SUBSTRING(@var,0,charindex('@',@var)) as UserName , Substring(@var,charindex('@',@var)+1,charindex('.',@var,charindex('@',@var,0))-(charindex('@',@var)+1)) as DomainName , substring(@var,charindex('.',@var,charindex('@',@var))+1,len(@var)) as Ext – Amardeep Apr 05 '18 at 06:38
  • this code split Email Address into three parts : UserName, DomainName,Ext. --- 'Abc.xyz@rediffmail.com' this mail has two dots. i try Vinay's (14 feb 2014) answer , that works but does not works like 'Abc.xyz@rediffmail.com' this Email . – Amardeep Apr 08 '18 at 01:52
  • i explain , SUBSTRING(@var,0,charindex('@',@var)) as UserName takes the string before '@' and second part works [@gmail - .com ]and return gmail then third part find '.' after '@' and return string (com). – Amardeep Apr 08 '18 at 01:55
1

I see the OP tagged the request as sql-server. I found this looking for mysql, go figure. So here is a mysql answer.

SUBSTRING_INDEX('john.doe@simon.says.com', '@', 1) AS Name,
SUBSTRING_INDEX(SUBSTRING_INDEX('john.doe@simon.says.com', '@', -1), '.', ROUND((LENGTH(SUBSTRING_INDEX('john.doe@simon.says.com', '@', -1)) - LENGTH(REPLACE(SUBSTRING_INDEX('john.doe@simon.says.com', '@', -1), '.', ''))) / LENGTH('.'))) AS DomainName,
SUBSTRING_INDEX('john.doe@simon.says.com', '.', -1) AS Extension,

The net result will return:

  • Name: john.doe
  • DomainName: simon.says
  • Extension: com
DanimalReks
  • 315
  • 4
  • 12