如何匹配和替换 SQL 中的字符串部分

How to match and replace sections of a string in SQL

我正在从我的数据库中提取一个热门网站列表,但我想合并来自同一域的结果。我已经能够通过使用 :

部分地做到这一点
REGEXP_REPLACE(site, '%|^www([123])?\.|^m\.|^mobile\.|^desktop\.')) as site

所以 "www.facebook.com" 和 "facebook.com" 或 "m.facebook.com" - 所有这些都出现在数据库中 - 当我执行 select distinct.

时被视为相同

但是,我想更进一步,编写一个表达式来查看句点之间的每个字符串。如果在句点之间的三个或更多字符串中连续找到匹配项,那么我想将它们视为相同。我根本无法预测每个可能出现在 "facebook.com" 或任何其他站点之前的字符串。

例如: "my.careerone.com.au" 和 "careerone.com.au" 三处匹配。

或者"yahoo.realestate.com.au"和"rs.realestate.com.au"三处匹配

关于如何实现这一点有什么想法吗?

我没有可用的 Vertica,因此我在 Oracle SQL 中对此进行了测试(它确实具有与 Vertica 类似的 REGEXP_REPLACE())。不确定 Vertica 中的 CTE 语法是什么,但无论如何您都会查询 table:

WITH d1 AS (
    SELECT 'my.careerone.com.au' AS domain_nm FROM dual
     UNION ALL
    SELECT 'careerone.com.au' FROM dual
     UNION ALL
    SELECT 'yahoo.realestate.com.au' FROM dual
     UNION ALL
    SELECT 'rs.realestate.com.au' FROM dual
)
SELECT domain_nm, TRIM('.' FROM REGEXP_REPLACE(domain_nm, '^.*((\.[^.]+){3})$', '')) AS domain_nm_fix
  FROM d1;

REGEXP_REPLACE() 在这里做的是 trim 域名的最高级别子域,如果它存在并且有超过 3 个级别。如果只有三个级别,则不会替换任何内容,因为正则表达式不匹配——这就是为什么前导 . 字符必须是 trimmed 的原因。因此,例如,careerone.com.au 将保持不变,而 my.careerone.com.au 将被 REGEXP_REPLACE() 更改为 .careerone.com.au,因此必须从中开始 . trim医学

@David 代码也可以在 Vertica 中运行,但性能方面可能不太好。

您可以使用 Vertica 自己的内部函数,例如 TRIM & REGEXP_REPLACE。 在 借用 @David Faber reg exp 之后,我以这个结束。

select TRIM(LEADING '.' from REGEXP_REPLACE(col_name,'^.*((\.[^.]+){3})$', '')) AS fixed_dn from table_name;