t1
id|entity_type
9|3
9|4
9|5
2|3
2|5
t2
id|entity_type
1|3
1|4
1|5
SELECT t1.id, array_agg(t1.entity_type)
FROM t1
GROUP BY
t1.id
HAVING ARRAY_AGG(t1.entity_type ORDER BY t1.entity_type) =
(SELECT ARRAY_AGG(t2.entity_type ORDER BY t2.entity_type)
FROM t2
WHERE t2.id = 1
GROUP BY t2.id);
结果:
t1.id = 9|array_agg{3,4,5}
我有两个表t1
和t2
。我想得到t1.id
的值,其中t1.entity_type
数组等于t2.entity_type
数组。
在这种情况下,一切都很好。对于t2.id = 1
,我接收t1.id = 9
。两者都有相同的entity_type
数组:{3,4,5}
现在我想得到t1.id
,不仅对于相等的集合,而且对于较小的集合。如果我这样修改t2
:
t2
id|entity_type
1|3
1|4
并以这种方式修改查询:
SELECT t1.id, array_agg(t1.entity_type)
FROM t1
GROUP BY
t1.id
HAVING ARRAY_AGG(t1.entity_type ORDER BY t1.entity_type) >= /*MODIFICATION*/
(SELECT ARRAY_AGG(t2.entity_type ORDER BY t2.entity_type)
FROM t2
WHERE t2.id = 1
GROUP BY t2.id);
我没有收到预期的结果:
t1.id = 1 has {3, 4, 5}
t2.id = 1 has {3, 4}
t1
中 * 包含 * t2
中的数组的数组应该符合条件。我希望像第一种情况一样收到结果,但我没有得到行。
有没有这样的方法:ARRAY_AGG
是否包含另一个ARRAY_AGG
?
1条答案
按热度按时间irlmq6kh1#
清理
使用两个不同的
array_agg()
调用将是低效的。使用相同的(SELECT
列表中的ORDER BY
和HAVING
子句):手册中的语法基础知识。
“contains”运算符**
@>
**与Nick commented类似,第二个查询将使用“array contains”运算符
@>
但这对于大table来说是非常低效的。
查询速度更快
这个问题可以转换为关系除法的情况。根据您的表定义,还有更有效的技术。我们在这个相关的问题下收集了一整套材料:
假设
(id, entity_type)
在两个表中都是唯一的,对于大表来说,这应该会快得多,特别是因为它可以在t1
上使用索引(而不是原始查询):你需要两个索引:
首先是
t2(id)
,通常由主键覆盖。第二:
添加的
id
列是可选的,以允许仅索引扫描。列的顺序至关重要:fiddle
老麻雀