[英]array_agg contains another array_agg
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 by t1.entity_type) =
(SELECT ARRAY_AGG(t2.entity_type 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 by t1.entity_type) >= /*MODIFICATION*/
(SELECT ARRAY_AGG(t2.entity_type 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?
首先,语法错误。 我猜你的意思是:
ARRAY_AGG(t1.entity_type ORDER BY t1.entity_type)
接下来,使用array_agg()
两个不同调用将是低效的。 使用相同的( SELECT
列表中的ORDER BY
和HAVING
子句):
SELECT id, array_agg(entity_type ORDER BY entity_type) AS arr
FROM t1
GROUP BY 1
HAVING array_agg(entity_type ORDER BY entity_type) = (
SELECT array_agg(entity_type ORDER BY entity_type)
FROM t2
WHERE id = 1
-- GROUP BY id -- not needed
);
@>
就像Nick评论的那样 ,你的第二个查询将与“包含”运算符@>
SELECT id, array_agg(entity_type ORDER BY entity_type) AS arr
FROM t1
GROUP BY 1
HAVING array_agg(entity_type ORDER BY entity_type) @> (
SELECT array_agg(entity_type ORDER BY entity_type)
FROM t2
WHERE id = 1
);
但对于大桌来说这是非常低效的 。
这是关系分裂的一个例子。 根据您(缺失的) 确切的表定义,有更有效的技术。 我们在这个相关问题下收集了整个武器库:
假设 (id, entity_type)
在两个表中都是唯一的,对于大表来说这应该快得多 ,特别是因为它可以在t1
上使用索引 (而不是原始查询):
SELECT t1.id
FROM t2
JOIN t1 USING (entity_type)
WHERE t2.id = 1
GROUP BY 1
HAVING count(*) = (SELECT count(*) FROM t2 WHERE id = 1);
你需要两个索引:
首先在t2.id
,通常由主键覆盖。
第二个关于t1.entity_type
:
CREATE INDEX t1_foo_idx ON t1 (entity_type, id);
添加的id
列是可选的,以允许仅索引扫描。 列的顺序是必不可少的:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.