[英]Count matches between multiple columns and words in a nested array
我先前的问题已解决。 现在,我需要开发一个相关但更复杂的查询。
我有一张这样的桌子:
id description additional_info
-------------------------------------------
123 games XYD
124 Festivals sport swim
我需要计算与数组匹配的次数,如下所示:
array_content varchar[] := {"Festivals,games","sport,swim"}
如果列description
和additional_info
中的任何一个包含用逗号分隔的任何标签,则我们将其计为1。因此,每个数组元素(由多个单词组成)只能对总数贡献1。
以上示例的结果应为:
id RID Matches
1 123 1
2 124 2
答案并不简单,但要弄清您的要求却比较困难:
SELECT row_number() OVER (ORDER BY t.id) AS id
, t.id AS "RID"
, count(DISTINCT a.ord) AS "Matches"
FROM tbl t
LEFT JOIN (
unnest(array_content) WITH ORDINALITY x(elem, ord)
CROSS JOIN LATERAL
unnest(string_to_array(elem, ',')) txt
) a ON t.description ~ a.txt
OR t.additional_info ~ a.txt
GROUP BY t.id;
准确产生您想要的结果。
array_content
是您搜索词的数组。
搜索项中外部数组的每个数组元素都是一个逗号分隔的列表。 通过取消嵌套两次来分解奇数构造(将外部数组的每个元素转换为另一个数组之后)。 例:
SELECT *
FROM unnest('{"Festivals,games","sport,swim"}'::varchar[]) WITH ORDINALITY x(elem, ord)
CROSS JOIN LATERAL
unnest(string_to_array(elem, ',')) txt;
结果:
elem | ord | txt
-----------------+-----+------------
Festivals,games | 1 | Festivals
Festivals,games | 1 | games
sport,swim | 2 | sport
sport,swim | 2 | swim
既然你要指望一次为每个外数组元素的比赛,我们生成与飞一个唯一的编号WITH ORDINALITY
。 细节:
现在我们可以在所需匹配的条件下将LEFT JOIN
到此派生表:
... ON t.description ~ a.txt
OR t.additional_info ~ a.txt
..并使用count(DISTINCT a.ord)
获得计数,即使多个搜索字词匹配,每个数组也仅计数一次。
最后,我在row_number() OVER (ORDER BY t.id) AS id
添加了神秘的id
row_number() OVER (ORDER BY t.id) AS id
假设它应该是序列号)。 Voilá。
正则表达式匹配( ~
)的注意事项与上一个问题相同:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.