我从我的数据库中提取了一个热门网站列表,但我想要合并来自同一个域的结果。我已经能够通过使用以下部分来做到这一点:
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”在三个地方匹配。
关于如何实现这一目标的任何想法?
答案 0 :(得分:2)
我没有Vertica可用,所以我在Oracle SQL中测试了它(它有REGEXP_REPLACE()
类似于Vertica的)。不确定Vertica中的CTE语法是什么,但无论如何你都要查询一个表:
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})$', '\1')) AS domain_nm_fix
FROM d1;
此处REGEXP_REPLACE()
的作用是修剪域名中最高级别的子域名(如果存在且超过3个级别)。如果只有三个级别,那么任何东西都不会被替换,因为正则表达式不匹配 - 这就是为什么必须修剪前导.
字符的原因。因此,例如,careerone.com.au
将保持不变,而my.careerone.com.au
将由.careerone.com.au
更改为REGEXP_REPLACE()
,然后必须从.
开始{{1}}修整。
答案 1 :(得分:2)
@David 代码也适用于Vertica,但性能不太好。
您可以使用Vertica自己的内部功能,例如TRIM & REGEXP_REPLACE
。
在借用 @David Faber reg exp之后,我对此感兴趣。
select TRIM(LEADING '.' from REGEXP_REPLACE(col_name,'^.*((\.[^.]+){3})$', '\1')) AS fixed_dn from table_name;