【发布时间】:2018-07-24 09:30:42
【问题描述】:
其中有最多 5 个元素的数组,例如给定:{1,2,3,4,5},我需要从该数组中获取所有可能的唯一组合,预期结果是:
{1}
{1,2}
{1,2,3}
{1,2,3,4}
{1,2,3,4,5}
{1,2,3,5}
{1,2,4}
{1,2,4,5}
{1,2,5}
{1,3}
{1,3,4}
{1,3,4,5}
{1,3,5}
{1,4}
{1,4,5}
{1,5}
{2}
{2,3}
{2,3,4}
{2,3,4,5}
{2,3,5}
{2,4}
{2,4,5}
{2,5}
{3}
{3,4}
{3,4,5}
{3,5}
{4}
{4,5}
{5}
我有这个解决方案:
create table temp_all_possible_cards (
card_ids int[]
);
create or replace function test(cards_in_hands INT[] )
returns void
as $$
begin
with all_possible_cards(ids) as(
select ARRAY_APPEND('{}'::int[], t1.card_ids)||ARRAY_APPEND('{}'::int[], t2.card_ids)||ARRAY_APPEND('{}'::int[], t3.card_ids)||ARRAY_APPEND('{}'::int[], t4.card_ids)||ARRAY_APPEND('{}'::int[], t5.card_ids)
from (
select unnest(cards_in_hands) as card_ids
) t1
cross join (
select unnest(cards_in_hands) as card_ids
) t2
cross join (
select unnest(cards_in_hands) as card_ids
) t3
cross join (
select unnest(cards_in_hands) as card_ids
) t4
cross join (
select unnest(cards_in_hands) as card_ids
) t5
)
INSERT INTO temp_all_possible_cards
SELECT DISTINCT uniq( sort(ids) ) from all_possible_cards;
end;
$$ language plpgsql
这可行,但有一个大问题,有时我需要运行此功能 5000 次
do $$
begin
for i in 1..5000 loop
perform test('{1,2,3,4,5}');
end loop;
end;
$$ language plpgsql
循环的执行时间为 55-60 秒。
问题:如何以有效的方式从数组中获取所有可能的唯一组合?如何优化这个方案,让 5000 次调用也明显快于 60 秒?
【问题讨论】:
-
嗯,我想你的交叉连接方法已经是解决这个问题的好方法了,尽管我不确定我在临时表中的插入是必要的,并且可以作为 SQL 函数而不是一个plPgsql。但如果可能输入的数量是有限的,您可以预先计算并将结果保存在表格中。因此,稍后您只需选择与给定输入匹配的记录。
标签: sql postgresql combinations postgresql-9.6