繁体   English   中英

array_agg包含另一个array_agg

[英]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}      

我有两个表t1t2 我想得到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 BYHAVING子句):

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列是可选的,以允许仅索引扫描。 列的顺序是必不可少的:

SQL小提琴。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM