我是新的Postgres有要求,在那里我需要从字符串字段中提取邮箱地址.可能有多个邮箱地址. 他说: 示例输入:

String
abc-cde-ghi-abc@test.com -cde@test.com
Finance-ddl-sample@yahoo.com-sample1@gmail.com-sample2@msn.com

没有固定的‘-’位置

输出:

abc@test.com;cde@test.com
sample@yahoo.com;sample1@gmail.com;sample2@msn.com

我已经try 了substring (string,'[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,6}'),能够获取一个邮箱地址,但不确定如何获取多个邮箱地址.有谁能帮忙吗?

推荐答案

首先让我说,这种数据库设计是一个非常糟糕的 idea ,损害了正常化规则.一般来说,一栏应该包含一个信息,而不是一堆邮件地址.最好创建一个映射表,其中单独存储一个人的所有邮件地址.

即使上面的改进对你来说是不可能的,不管是什么原因,试着找一个更好的分隔符来标明不同邮件地址之间的"边界".我知道许多人在他们的邮件地址中使用-,所以我怀疑你会通过这种方式得到你想要的东西.

但不管怎样,这些问题由你来处理.这里有一个选项可以获得你的预期结果:

WITH separatedMailAddresses AS
  (SELECT 
    email, 
    UNNEST(
      STRING_TO_ARRAY(email, '-')
    ) AS parts 
   FROM yourtable
   GROUP BY email)
SELECT 
  email,
  REPLACE(STRING_AGG(parts, ',')
  FILTER (WHERE parts LIKE '%@%'),' ','') AS email_list
FROM separatedMailAddresses
GROUP BY email;

这将产生您在问题中描述的结果.如果不需要,请从第二个查询中删除邮箱列.

试试看here

一些关于那里发生的事情的解释:

UNNESTSTRING_TO_ARRAY的组合是众所周知的"变通办法",可以构建SPLIT_PART函数,而不必提供位置作为参数.SPLIT_PART函数需要一个字符串、一个分隔符和我们要获取的部分的位置.但您不想只获取某一部分,而是要获取-之间的所有部分.据我所知,这是不可能的内置函数.

为了从不同的邮件地址创建逗号分隔的列表,我们可以使用STRING_AGG.但是我们必须删除那些不包含@的"邮件地址",因为这些字符串不应该出现在结果中.因此,我们有LIKE的这个条件.

我们现在创建的邮件地址列表可能包含空格(对于您的示例数据,实际上就是这种情况).所以我们用REPLACE把它们go 掉.

Sql相关问答推荐

创建每小时重置的序列号

Oracle SQL中的累计总数

对于表A中的每一行,更新表B中与金额有关的行

如何使用ROW_NUM() Select 一个没有第二条记录的实例?

在请求结束之前,PostgreSQL不会考虑使用中的删除

从依赖于其他表的值的XREF表中的值分组获得正确的计数?

对列进行排序后,基于两列删除重复行

将计算列设置为持久化的目的是什么?

将所有XML文件导入到SQL Server中

如何为缺少的类别添加行

SQL Server 查询 WHERE LIKE

如何解释 SQL Server 中的 Foxpro 语法?

一次 Select 语句中按组累计的SQL累计数

批量更改WooCommerce中所有产品的税收状态

如何按日期和位置对最近 3 个报告日期的 SQL 查询结果进行透视?

SQLite 中的过滤运行总和视图

从每行中排除最大元素

如何在一个存储过程中创建全局临时表,并在另一个存储过程中使用它

使用一组值进行分组和计数

如何优化sql请求?