Sql 仅从电子邮件地址列表中提取用户名

Sql 仅从电子邮件地址列表中提取用户名,sql,sql-server,function,Sql,Sql Server,Function,我只需要从包含电子邮件地址列表的列中提取用户名,列表之间用分隔 [栏目名称] 电子邮件地址 user1@gmail.com;user2@gmail.com;user3@gmail.com 我希望输出为user1;用户2;用户3 如何在sql查询中获取它?您真的应该永远不要在一个单元格中存储多个值 这正在破坏1。NF已经… 您应该做的是:引入一个与1:n相关的表,分别向其所有者存储每个带有外键的电子邮件地址 对于SQL Server 2016,您可以使用STRING\u SPLIT(),但对于您

我只需要从包含电子邮件地址列表的列中提取用户名,列表之间用
分隔

[栏目名称] 电子邮件地址

user1@gmail.com;user2@gmail.com;user3@gmail.com
我希望输出为
user1;用户2;用户3


如何在sql查询中获取它?

您真的应该永远不要在一个单元格中存储多个值
这正在破坏
1。NF
已经…
您应该做的是:引入一个与
1:n
相关的表,分别向其所有者存储每个带有外键的电子邮件地址

对于SQL Server 2016,您可以使用
STRING\u SPLIT()
,但对于您的版本,您必须使用众多解决方法之一。在下面的代码中,我首先使用XML技巧在每个分号处拆分字符串。最后一个
选择
组合了
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)
DECLARE@mockup TABLE(您的电子邮件VARCHAR(100));
插入到@mockup值中
('us&er1@gmail.com;user2@gmail.com;user3@gmail.com');
选择左侧(eMailAddress.value(N'text()[1],'nvarchar(max)')、CHARINDEX('@',eMailAddress.value(N'text()[1],'nvarchar(max)'))-1)
来自@mockup AS m
交叉应用(选择CAST(“”+REPLACE((选择REPLACE(m.yourmail,“;”,“$$SplitThisHere$$”)作为[*]作为XML路径(“”)),“$$SplitThisHere$$,”)+“”作为XML)作为(xmlSplit)
交叉应用A.xmlspilt.nodes(N'/x[text()])作为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,'')
选择素材(
(
选择“;”+左键(eMailAddress.value(N'text()[1],'nvarchar(最大值)”),CHARINDEX('@',eMailAddress.value(N'text()[1],'nvarchar(最大值))-1)
来自@mockup AS m
交叉应用(选择CAST(“”+REPLACE((选择REPLACE(m.yourmail,“;”,“$$SplitThisHere$$”)作为[*]作为XML路径(“”)),“$$SplitThisHere$$,”)+“”作为XML)作为(xmlSplit)
交叉应用A.xmlspilt.nodes(N'/x[text()])作为B(eMailAddress)
对于XML路径(“”),键入
).value('text()[1]','nvarchar(max'),1,1',)

你真的应该永远不要在一个单元格中存储多个值
这正在破坏
1。NF
已经…
您应该做的是:引入一个与
1:n
相关的表,分别向其所有者存储每个带有外键的电子邮件地址

对于SQL Server 2016,您可以使用
STRING\u SPLIT()
,但对于您的版本,您必须使用众多解决方法之一。在下面的代码中,我首先使用XML技巧在每个分号处拆分字符串。最后一个
选择
组合了
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)
DECLARE@mockup TABLE(您的电子邮件VARCHAR(100));
插入到@mockup值中
('us&er1@gmail.com;user2@gmail.com;user3@gmail.com');
选择左侧(eMailAddress.value(N'text()[1],'nvarchar(max)')、CHARINDEX('@',eMailAddress.value(N'text()[1],'nvarchar(max)'))-1)
来自@mockup AS m
交叉应用(选择CAST(“”+REPLACE((选择REPLACE(m.yourmail,“;”,“$$SplitThisHere$$”)作为[*]作为XML路径(“”)),“$$SplitThisHere$$,”)+“”作为XML)作为(xmlSplit)
交叉应用A.xmlspilt.nodes(N'/x[text()])作为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,'')
选择素材(
(
选择“;”+左键(eMailAddress.value(N'text()[1],'nvarchar(最大值)”),CHARINDEX('@',eMailAddress.value(N'text()[1],'nvarchar(最大值))-1)
来自@mockup AS m
交叉应用(选择CAST(“”+REPLACE((选择REPLACE(m.yourmail,“;”,“$$SplitThisHere$$”)作为[*]作为XML路径(“”)),“$$SplitThisHere$$,”)+“”作为XML)作为(xmlSplit)
交叉应用A.xmlspilt.nodes(N'/x[text()])作为B(eMailAddress)
对于XML路径(“”),键入
).value('text()[1]','nvarchar(max'),1,1',)

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

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

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

Declare @email nvarchar(50)='user1@gmail.com'
Select Substring(@email,0,CharIndex('@',@email))
将电子邮件字符串重新命名为函数

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
输出

  EmailDesiredOutPut
  --------------
  user1;  user2;  user3
EmailDesiredOutPut
-------------------
user1; user2; user3
将电子邮件字符串重新命名为函数

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
输出

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


哪种类型的sql数据库?sql server 2012邮件域是否始终相同?我的意思是它总是@gmail.com还是可以变化?不,它不是@gmail.com总是,它可以变化哪种类型的sql数据库?sql server 2012是邮件域始终相同?我的意思是,它总是@gmail.com,还是可以改变?不,它不是@gmail.com,它可以。varyOP提到,只有一列包含电子邮件地址列表user1@gmail.com;user2@gmail.com;user3@gmail.com'如果列保持这样的数据,则代码将不起作用'user1@gmail.com;user2@gmail.com;user3@gmail.com;user4@gmail.com;user5@gmail.comOP提到,只有一列包含电子邮件地址列表user1@gmail.com;user2@gmail.com;user3@gmail.com'如果列保持这样的数据,则代码将不起作用'user1@gmail.com;user2@gmail.com;user3@gmail.com;user4@gmail.com;user5@gmail.com“谢谢,它工作正常,但我正在尝试将其放入函数中,当我设置输出变量时,它会抛出错误--->关键字“set”附近的语法不正确。请检查发布的问题,我已经通过添加函数进行了编辑OK我将通过添加函数进行编辑。感谢它工作正常,但我正在尝试将其放入函数中,当我设置输出变量时,它会在关键字“set”附近抛出错误-->错误语法。请检查发布的问题,我已经通过添加函数进行了编辑OK我将进行编辑。