查找最小列数与模式匹配的行

时间:2016-12-11 21:56:20

标签: sql postgresql pattern-matching

我有一个类似以下的架构(只是一个例子):

CREATE TABLE example (
  id    int primary key
, text1 text
, text2 text
, text3 text
, text4 text
, text5 text
, text6 text
);

问题:

我正在尝试使用~*运算符在6个文本列上运行匹配模式。我可以通过6列中模式的出现次数来查询示例表吗?

示例:

我想查找6个文本列中至少3个中包含所述关键字的所有行。无论哪6列都没关系。

2 个答案:

答案 0 :(得分:2)

您可以通过以下简单方式找到许多匹配项:

insert into example values (1, 'a', 'a', 'a', 'b', 'c', 'd');

select 
    id, 
    (text1 ~* 'a')::int+ (text2 ~* 'a')::int+ 
    (text3 ~* 'a')::int+ (text4 ~* 'a')::int+ 
    (text5 ~* 'a')::int+ (text6 ~* 'a')::int as matches
from example;

 id | matches 
----+---------
  1 |       3

如果性能不是一个关键问题,你可以使用更方便但更慢的查询:

select id, sum((t ~* 'a')::int) as matches
from example,
lateral unnest(array[text1, text2, text3, text4, text5, text6]) as t
group by 1;

您可以使用WHERE(查询#1)或HAVING(查询#2)子句中的表达式:

select *
from example
where
    (text1 ~* 'a')::int+ (text2 ~* 'a')::int+ 
    (text3 ~* 'a')::int+ (text4 ~* 'a')::int+ 
    (text5 ~* 'a')::int+ (text6 ~* 'a')::int > 3;

select e.*
from example e,
lateral unnest(array[text1, text2, text3, text4, text5, text6]) as t
group by e.id
having sum((t ~* 'a')::int) > 3;

答案 1 :(得分:0)

klin posted类似,但这应该更简单,更快:

unittest

关于SELECT e.* FROM example e JOIN LATERAL ( SELECT count(*) FILTER (WHERE x.t ~* 'keyword') AS ct FROM (VALUES(text1), (text2), (text3), (text4), (text5), (text6)) x(t) ) sub ON sub.ct >= 3; -- your minimum number of columns here 加入中的VALUES

关于汇总LATERAL