tim*_*one 6 postgresql aggregate array
我正在处理启用了intarray扩展的 Postgres 9.4项目。我们有一个看起来像这样的表:
items
-------------------------------------
id name tag_ids
--------------------------------------
1 a car {1,4}
2 a room to rent {1}
3 a boat {1,2,4,11}
4 a wine {2}
5 emily {3}
Run Code Online (Sandbox Code Playgroud)
如果可能,我想对标签 ID 进行分组。就像获取具有tag_id
“{1,2,4,11}”的所有元素的计数
tag_id count
1 3
2 2
4 2
11 1
Run Code Online (Sandbox Code Playgroud)
这可能吗?我会认为这样的交叉点:
select * from items where tag_ids && '{1,2,4,11}'
Run Code Online (Sandbox Code Playgroud)
但我需要按交集结果内的数组元素进行分组。如果我按 tag_ids 分组,它只是唯一值。
我该怎么做?
保留您已经必须使用索引廉价识别具有任何相关数组元素的行的基本查询。
然后tag_ids & '{1,2,4,11}'
在LATERAL
连接中仅取消嵌套交集 ( ) 。最后,汇总:
SELECT tag_id, count(*) AS ct
FROM items i
, unnest(tag_ids & '{1,2,4,11}'::int[]) tag_id
WHERE tag_ids && '{1,2,4,11}'::int[]
GROUP BY tag_id
ORDER BY count(*) DESC;
Run Code Online (Sandbox Code Playgroud)
再一次,intarray 模块的交集运算符&
是有用的。
之前的相关回答:
如果您还没有intarray
安装,或者对于任何其他数组类型,我们需要另一个连接:
SELECT tag_id, count(*) AS ct
FROM (
SELECT *
FROM items
WHERE tag_ids && '{1,2,4,11}'::int[]
) i, unnest(tag_ids) t(tag_id)
JOIN unnest('{1,2,4,11}'::int[]) x(tag_id) USING (tag_id)
GROUP BY tag_id
ORDER BY count(*) DESC;
Run Code Online (Sandbox Code Playgroud)
细微的区别:交集运算符折叠重复项以生成不同的元素,而此查询不会。仅当可以有重复的数组元素时才重要......
SQL Fiddle 演示了 和 一个额外的行,该行混合了匹配和不匹配的元素,以证明需要交集或附加连接来消除不需要的元素。
归档时间: |
|
查看次数: |
2794 次 |
最近记录: |