我有一张表,其中一列包含一个字符串中的多个电子邮件地址或名称:
+----+-------------------------------------------------------+
| id ¦ emails ¦
+----+-------------------------------------------------------+
| 1 ¦ John Doe; jdoe@gmail.com; Company IT; jd@company.com; ¦
+----+-------------------------------------------------------+
| 2 ¦ jane@company.com; Jane Doe; jd@company.com; ¦
+----+-------------------------------------------------------+
我需要评估电子邮件列,以确定是否有外部电子邮件地址(例如jdoe@gmail.com
)。因此,我需要将列emails
中的值拆分为单独的字符串并评估每个字符串。最后,我想用一个附加列更新该表,该列指示电子邮件是内部的还是外部的。
+----+-------------------------------------------------------+-----------+
| id ¦ emails ¦ flag ¦
+----+-------------------------------------------------------+-----------+
| 1 ¦ John Doe; jdoe@gmail.com; Company IT; jd@company.com; ¦ external ¦
+----+-------------------------------------------------------+-----------+
| 2 ¦ jane@company.com; Jane Doe; jd@company.com; ¦ internal ¦
+----+-------------------------------------------------------+-----------+
我设法使用STRING_SPLIT()
分割了一个字符串,并进行了我想要的评估(某种程度)。
DECLARE @flag int
SELECT @flag=COUNT(*) FROM STRING_SPLIT('John Doe; jdoe@gmail.com; Company IT; jd@company.com;', ';')
WHERE value LIKE '%@%'AND value NOT LIKE '%Company%'
IF (@flag > 0)
BEGIN
Print 'extern'
END
ELSE
BEGIN
Print 'intern'
END
但是,现在我将字符串传递给STRING_SPLIT()
函数。我想传递emails
列,并根据评估结果更新表。任何想法如何实现这一目标?
答案 0 :(得分:1)
您可以在select
中执行以下操作:
select t.*,
(case when e.cnt > 0 then 'external' else 'internal' end) as flag
from t cross apply
(select count(*) as cnt
from string_split(t.emails, ';') s
where value LIKE '%@%' AND value NOT LIKE '%Company%'
) e;
注意:这保留了OP识别“内部”与“外部”的原始逻辑。问题似乎与那无关。显然,此版本混淆了用户名和域组件,因此,即使OP可能希望用户名是“外部”,用户名实际上也可能包含公司名称。
通常,我会警告不要在一个列中存储多个值,建议使用更规范的结构-一个表,每行一封电子邮件。我确实了解,有时电子邮件列表仅用于传递给电子邮件程序,并且需要采用特定格式。在这种情况下,它们通常被视为黑盒,并且通常不会在SQL中进行解析,因此它们是该规则的合理例外。