如何将 array_agg 之后的整数数组转换为 IN 子句的值
how to convert array of integers after array_agg into values for IN clause
能不能帮帮我,我已经尝试解决这个问题很长时间了...
我有 table Product 和 RelatedProducts(顶级产品由其他基础产品组成)。目标:我想要获得所有基础产品。
所以,table 看起来像:
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
馈入产品 table 以获取所有相关产品。
所以,实际上我通过 运行
从所有必要的值中创建了数组
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) 转换为值...或者您可以建议不同的更好方法?
Goal: I'd like get all base products.
如果我假设 "base" 产品从未出现在 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 示例中的错误是:
在最后一个查询中只是 unnest
数组而不是 array_to_string
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 理论上可以 return 多行,它对待你的 array_agg 有点像嵌套数组的内部数组。 ANY "unnests" 第一层,但仍保留一个 int[] 层供 =
使用。
但是如果您只是去掉聚合,您的 IN 示例就可以工作:
由于您没有为您的表提供创建脚本,我已经用 pgbench 中的脚本进行了替换,以便我可以 post 测试代码。这个概念应该适用于您的表格。
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);
列表、数组和集合是不同的东西。但在某些情况下它们可以互换使用。但是我不知道如何在不尝试的情况下预测哪些。
如果要将结果用作数组,可以使用 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))
能不能帮帮我,我已经尝试解决这个问题很长时间了... 我有 table Product 和 RelatedProducts(顶级产品由其他基础产品组成)。目标:我想要获得所有基础产品。 所以,table 看起来像:
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
馈入产品 table 以获取所有相关产品。
所以,实际上我通过 运行
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) 转换为值...或者您可以建议不同的更好方法?
Goal: I'd like get all base products.
如果我假设 "base" 产品从未出现在 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 示例中的错误是:
在最后一个查询中只是 unnest
数组而不是 array_to_string
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 理论上可以 return 多行,它对待你的 array_agg 有点像嵌套数组的内部数组。 ANY "unnests" 第一层,但仍保留一个 int[] 层供 =
使用。
但是如果您只是去掉聚合,您的 IN 示例就可以工作:
由于您没有为您的表提供创建脚本,我已经用 pgbench 中的脚本进行了替换,以便我可以 post 测试代码。这个概念应该适用于您的表格。
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);
列表、数组和集合是不同的东西。但在某些情况下它们可以互换使用。但是我不知道如何在不尝试的情况下预测哪些。
如果要将结果用作数组,可以使用 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))