我有一个类似以下的架构(只是一个例子):
CREATE TABLE example (
id int primary key
, text1 text
, text2 text
, text3 text
, text4 text
, text5 text
, text6 text
);
问题:
我正在尝试使用~*
运算符在6个文本列上运行匹配模式。我可以通过6列中模式的出现次数来查询示例表吗?
示例:
我想查找6个文本列中至少3个中包含所述关键字的所有行。无论哪6列都没关系。
答案 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
: