给定一个包含2个cols的表,id(bigserial)和tags(varchar(64)[])
id|tags
--------
1 |a,b,c
2 |a,c
3 |d,e
根据标签交集计数(ic)获取行的最佳查询是什么?
所以搜索a,b,c将返回
id|ic
-----
1 |3
2 |2
3 |0
答案 0 :(得分:1)
SELECT t.id, count(tag = ANY ('{a,b,c}') OR NULL) AS ic
FROM tbl t
, unnest(tags) x(tag)
GROUP BY 1;
那是implicit JOIN LATERAL
。排除带有空数组或NULL数组的行。要包含,请使用:
LEFT JOIN unnest(tags) x(tag) ON TRUE
OTOH,如果您只对至少有一个匹配的行感兴趣,可以使用overlap array operator &&
预先选择以获得更好的效果:
SELECT t.id, count(tag = ANY ('{a,b,c}') OR NULL) AS ic
FROM (SELECT * tbl WHERE tags && '{a,b,c}') t
, unnest(tags) x(tag)
GROUP BY 1;
GIN索引可以支持 &&
,这对于一个大表来说会有所不同。
有关计数技术的更多信息:
答案 1 :(得分:0)
SELECT id, IF(('a' = ANY(tags)),1,0) + IF(('b' = ANY(tags)),1,0) + IF(('c' = ANY(tags)),1,0) AS ic
FROM mytable