【问题标题】:PostgreSQL logical AND for finding two values in the substringPostgreSQL 逻辑 AND 用于在子字符串中查找两个值
【发布时间】:2021-02-24 22:52:03
【问题描述】:
我有一个数据集,其中包含来自社交媒体网站的许多文本 cmet。我想查找文本中至少包含两个国家/地区名称的所有实例。我现在的样子:
SELECT * FROM comments WHERE body ~* '(Canada|United States|Mexico)'
这让我可以找到任何提及这三个国家的实例。但是,如果我想找到其中至少有两个名称存在的实例呢?
【问题讨论】:
标签:
sql
string
postgresql
count
where-clause
【解决方案1】:
一种方法是对每个单独进行比较并将匹配项相加:
WHERE ( (body ~* 'Canada')::int + (body ~* 'United States')::int + (body ~* 'Mexico)::int) >= 2
但是,拆分文本并使用数组函数可能会更好:
WHERE string_to_array(body, ' ') @> array['Canada', 'Mexico', 'United States']
当然,具体的拆分逻辑取决于body 的样子。
另一个有趣的方法是横向连接:
SELECT c.*
FROM comments c CROSS JOIN LATERAL
(SELECT COUNT(*) as num_matches
FROM (VALUES ('Canada'), ('Mexico'), ('United States')) v(str)
WHERE c.body ~* v.str -- or use `like`
) x
WHERE num_matches >= 2;
【解决方案2】:
您可以独立检查每个条件,将布尔结果转换为整数,并确保匹配总和至少为2:
where (
(body ilike '%Canada%')::int
+ (body ilike '%United States%')::int
+ (body ilike '%Mexico%')::int
) >= 2
当然这也适用于正则表达式,尽管这可能不如like 高效:
WHERE (
(body ~* 'Canada')::int
+ (body ~* 'United States')::int
+ (body ~* 'Mexico')::int
) >= 2