繁体   English   中英

如何将array_agg之后的整数数组转换为IN子句的值

[英]how to convert array of integers after array_agg into values for IN clause

可以请帮助我,我正在尝试解决这个问题很长一段时间......我有表格产品和相关产品(顶级产品由其他基础产品组成)。 目标:我想获得所有基础产品。 所以,表看起来像:

product_id   related_product_ids                
------------------------------------------------
1143         1213                               
1255         1245                               
1261         1229,1239,1309,1237,1305,1243,1143

我通过查询得到了这个:

select max(p.id) as product_id, array_to_string(array_agg(p2p.related_product_id), ',') as related_product_ids 
from product p 
  left join product_to_product p2p on p2p.product_id = p.id
where p.id in (select product_id from order_line where wo_id = 262834)
group by p.id, p2p.product_id

我想将related_product_ids输入产品表以获取所有相关产品。 所以,实际上我通过运行从所有必要的值中创建了数组

select array_agg(p2p.related_product_id) as id 
from product p 
  left join product_to_product p2p on p2p.product_id = p.id 
where p.id in (select product_id from order_line where wo_id = 262834)
related_product_ids           
---------------------------------------------
{1309,1143,1229,1239,1243,1237,1305,1245,1213}

我尝试了以下操作,但没有成功:

select * 
from product 
where id = ANY(select array_agg(p2p.related_product_id) as id 
               from product p 
                 left join product_to_product p2p on p2p.product_id = p.id
               where p.id in (select product_id from order_line where wo_id =  262834))
Error: ERROR: operator does not exist: integer = integer[] Hint: No operator matches the given name and argument type(s). You might need to add explicit type casts. Position: 39, SQLState: 42883, ErrorCode: 0

或以下:

select * 
from product 
where id in (select array_to_string(array_agg(p2p.related_product_id), ',') as id 
             from product p 
               left join product_to_product p2p on p2p.product_id = p.id
             where p.id in (select product_id from order_line where wo_id = 262834))
Error: ERROR: operator does not exist: integer = integer[] Hint: No operator matches the given name and argument type(s). You might need to add explicit type casts. Position: 36, SQLState: 42883, ErrorCode: 0

和许多其他尝试

所以最后我需要的是

select * 
from product 
where id in (1309,1143,1229,1239,1243,1237,1305,1245,1213)

(来自related_product_ids的值)

如何将整数数组(related_product_ids)转换为值....或者您可以建议不同的更好方法?

DBFiddle

如果要将结果用作数组,则可以使用ANY - 但参数也必须是数组。

select * 
from product 
where id = any(array(select p2p.related_product_id
                     from product p 
                       left join product_to_product p2p on p2p.product_id = p.id
                     where p.id in (1, 2, 3)))

但我认为你把事情复杂化了。 据我所知,这可以简化为:

select p1.*
from product p1
where exists (select *
              from product_to_product p2p
              where p2p.related_product_id = p1.id
                and p2p.product_id in (1,2,3))

目标:我想获得所有基础产品。

如果我假设“基本”产品是从未出现在related_product_id列中的产品,那么not exists就会出现:

select p.*
from product p
where not exists (select 1 
                  from  product_to_product p2p
                  where p2p.related_product_id = p.id
                 );

您的 DBFiddle 示例中的错误是:

在最后一个查询中,只需array_to_string数组而不是unnest

select * from product where id = ANY(select unnest(array_agg(p2p.related_product_id)) as id from product p 
        left join product_to_product p2p on p2p.product_id = p.id
        where p.id in (1, 2, 3))

我不知道为什么您的 =ANY 不起作用,在我看来应该如此。 因为 select 理论上可以返回多行,所以它会将您的 array_agg 视为嵌套数组的内部数组。 ANY “取消嵌套”第一层,但仍然留下一个 int[] 层供=使用。

但是,如果您只是摆脱聚合,您的 IN 示例就可以工作:

由于您没有为您的表提供创建脚本,我已经从 pgbench 替换了脚本,以便我可以发布经过测试的代码。 这个概念应该适用于您的表格。

select * from pgbench_accounts where aid in (select bid from pgbench_branches);

请注意,当您不聚合时,ANY 也适用:

select * from pgbench_accounts where aid =ANY (select bid from pgbench_branches);

列表和 arrays 和集合是不同的东西。 但在某些情况下,它们可以互换使用。 但我不知道如何在不尝试的情况下预测哪些。

暂无
暂无

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

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