gpt4 book ai didi

sql - 以有效的方式从数组元素中获取所有可能的组合

转载 作者:行者123 更新时间:2023-11-29 14:31:15 25 4
gpt4 key购买 nike

数组中最多有 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 秒快得多?

最佳答案

;WITH NOS AS (SELECT 1 aval 
UNION ALL
SELECT aval + 1 FROM NOS WHERE aval < 2 * 2 * 2 * 2 * 2 - 1
)
SELECT LEFT(IQ.x, LEN(IQ.x) - 1) + '}' FROM (
SELECT RTRIM('{'
+ CASE WHEN aval & 1 != 0 THEN '1, ' ELSE '' END
+ CASE WHEN aval & 2 != 0 THEN '2, ' ELSE '' END
+ CASE WHEN aval & 4 != 0 THEN '3, ' ELSE '' END
+ CASE WHEN aval & 8 != 0 THEN '4, ' ELSE '' END
+ CASE WHEN aval & 16 != 0 THEN '5, ' ELSE '' END) AS X
FROM NOS) IQ

显示基准

create table #test (x nvarchar(50))

declare @i int = 0;

declare @s datetime2 = sysutcdatetime();

while @i < 5000
begin

;WITH NOS AS (SELECT 1 aval
UNION ALL
SELECT aval + 1 FROM NOS WHERE aval < 2 * 2 * 2 * 2 * 2 - 1
)
insert #test SELECT LEFT(IQ.x, LEN(IQ.x) - 1) + '}' FROM (
SELECT RTRIM('{'
+ CASE WHEN aval & 1 != 0 THEN '1, ' ELSE '' END
+ CASE WHEN aval & 2 != 0 THEN '2, ' ELSE '' END
+ CASE WHEN aval & 4 != 0 THEN '3, ' ELSE '' END
+ CASE WHEN aval & 8 != 0 THEN '4, ' ELSE '' END
+ CASE WHEN aval & 16 != 0 THEN '5, ' ELSE '' END) AS X
FROM NOS) IQ


set @i = @i + 1;

end

DECLARe @usTiming BIGINT = datediff(MICROSECOND, @s ,sysutcdatetime())

select CAST(@usTiming as nvarchar(19)) + 'us = ' + CAST(CAST(@usTiming/1000000.000000000000 as dec(10,3)) as nvarchar(20)) + ' seconds';

drop table #test

我有 2.5 秒

关于sql - 以有效的方式从数组元素中获取所有可能的组合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51495180/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com