从电子邮件地址列表中单独提取用户名

时间:2017-05-18 06:55:20

标签: sql sql-server function

我只需要从包含[assembly: AssemblyTitle("Title")] [assembly: AssemblyDescription("******")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("*********")] [assembly: AssemblyProduct("*******")] [assembly: AssemblyCopyright("*******")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] // Setting ComVisible to false makes the types in this assembly not visible // to COM components. If you need to access a type in this assembly from // COM, set the ComVisible attribute to true on that type. [assembly: ComVisible(false)] // Version information for an assembly consists of the following four values: // // Major Version // Minor Version // Build Number // Revision // // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("3.0.0.37")] [assembly: AssemblyFileVersion("3.0.0.37")] [assembly: InternalsVisibleTo("*******")]

分隔的电子邮件地址列表的列中提取用户名

[列名] 电子邮件地址

{{1}}

我希望输出为{{1}}

如何在sql查询中获取它?

3 个答案:

答案 0 :(得分:3)

DECLARE @TempData TABLE(YourEMail VARCHAR(100));
INSERT INTO @TempData VALUES
    ('user1@gmail.com;user2@gmail.com;user3@gmail.com');

;WITH Expected
AS (
    SELECT SUBSTRING(YourEMail, 1, CHARINDEX('@', YourEMail) - 1) AS YourEMail
    FROM (
        SELECT Split.a.value('.', 'VARCHAR(100)') AS YourEMail
        FROM (
            SELECT 
                CAST('<S>' + REPLACE(YourEMail, ';', '</S><S>') + '</S>' AS XML) AS YourEMail
            FROM @TempData
            ) AS A
        CROSS APPLY YourEMail.nodes('/S') AS Split(a)
        ) dt
    )
SELECT DISTINCT STUFF((
            SELECT '; ' + YourEMail
            FROM Expected
            FOR XML PATH('')
            ), 1, 1, '') AS EmailDesiredOutPut

输出

  EmailDesiredOutPut
  --------------
  user1;  user2;  user3

重新发布Email_String AS功能

CREATE FUNCTION [dbo].[udf_ExtractName] (
@YourEMailIn nvarchar(MAX)
)
Returns varchar(max)
AS
Begin
DECLARE @YourEMailOut varchar(MAX)

DECLARE @TempData TABLE(YourEMail VARCHAR(100));
INSERT INTO @TempData(YourEMail) 

SELECT @YourEMailIn

;WITH Expected
AS (
    SELECT SUBSTRING(YourEMail, 1, CHARINDEX('@', YourEMail) - 1) AS YourEMail
    FROM (
        SELECT Split.a.value('.', 'VARCHAR(100)') AS YourEMail
        FROM (
            SELECT 
                CAST('<S>' + REPLACE(YourEMail, ';', '</S><S>') + '</S>' AS XML) AS YourEMail
            FROM @TempData
            ) AS A
        CROSS APPLY YourEMail.nodes('/S') AS Split(a)
        ) dt
    )
    , FinalResult
    AS (
SELECT  DISTINCT STUFF((
            SELECT '; ' + YourEMail
            FROM Expected
            FOR XML PATH('')
            ), 1, 1, '') AS EmailDesiredOutPut
       )
       SELECT @YourEMailOut=EmailDesiredOutPut From FinalResult

       RETURN @YourEMailOut

END
GO

- 如下所示调用函数

 SELECT [dbo].[udf_ExtractName] ( 'user1@gmail.com;user2@gmail.com;user3@gmail.com') AS EmailDesiredOutPut 

输出

EmailDesiredOutPut
-------------------
user1; user2; user3

答案 1 :(得分:2)

你应该永远不会在一个单元格中存储多个值!!!
这已经打破了1.NF ...... 您应该做什么:引入一个与1:n相关的表,将每个电子邮件地址与一个外键分别存储到其所有者。

使用SQL Server 2016,您可以使用STRING_SPLIT(),但是对于您的版本,您必须使用众多解决方法之一。在下面的代码中,我首先使用 XML技巧在每个分号处拆分字符串。最终的SELECT结合LEFT()CHARINDEX来消除其余部分:

尝试这样

DECLARE @mockup TABLE(YourEMail VARCHAR(100));
INSERT INTO @mockup VALUES
    ('us&er1@gmail.com;user2@gmail.com;user3@gmail.com');

SELECT LEFT(eMailAddress.value(N'text()[1]','nvarchar(max)'),CHARINDEX('@',eMailAddress.value(N'text()[1]','nvarchar(max)'))-1)
FROM @mockup AS m
CROSS APPLY(SELECT CAST('<x>' + REPLACE((SELECT REPLACE(m.YourEMail,';','$$SplitThisHere$$') AS [*] FOR XML PATH('')),'$$SplitThisHere$$','</x><x>') + '</x>' AS XML)) AS A(xmlSplit)
CROSS APPLY A.xmlSplit.nodes(N'/x[text()]') AS B(eMailAddress)

如果您需要再次重新连接用户名(请考虑这一点!),您可以将最终查询更改为:

SELECT STUFF(
(
SELECT ';' + LEFT(eMailAddress.value(N'text()[1]','nvarchar(max)'),CHARINDEX('@',eMailAddress.value(N'text()[1]','nvarchar(max)'))-1)
FROM @mockup AS m
CROSS APPLY(SELECT CAST('<x>' + REPLACE((SELECT REPLACE(m.YourEMail,';','$$SplitThisHere$$') AS [*] FOR XML PATH('')),'$$SplitThisHere$$','</x><x>') + '</x>' AS XML)) AS A(xmlSplit)
CROSS APPLY A.xmlSplit.nodes(N'/x[text()]') AS B(eMailAddress)
FOR XML PATH(''),TYPE
).value('text()[1]','nvarchar(max)'),1,1,'')

答案 2 :(得分:0)

您可以简单地使用此代码。只需用列名替换变量名。

Declare @email nvarchar(50)='user1@gmail.com'
Select Substring(@email,0,CharIndex('@',@email))