【问题标题】:All Permutations of an Array数组的所有排列
【发布时间】:2020-10-12 19:24:02
【问题描述】:
【问题讨论】:
标签:
sql
arrays
postgresql
select
【解决方案1】:
这是一种使用递归 cte 的方法:
with recursive
data as (select array[1, 2, 3] arr),
keys as (select generate_subscripts(d.arr, 1) as rn from data d),
cte as (
select d.arr initial_arr, array[d.arr[k.rn]] new_arr, array[k.rn] used_rn
from data d
cross join keys k
union all
select initial_arr, c.new_arr || c.initial_arr[k.rn], used_rn || k.rn
from cte c
inner join keys k on not (k.rn = any(c.used_rn))
)
select new_arr from cte
从一个给定的数组开始(这里由cte data定义),想法是提取所有带有generate_subscript()(cte keys)的数组索引,然后递归遍历数组。我们需要跟踪我们已经使用过的键,因此我们只选择每个值一次。
这会产生所有可能的组合。如果只需要 1 元素和 2 元素组合,可以在递归 cte 中添加 where 子句,例如 where array_length(c.new_ar) < 2。
Demo on DB Fiddle
【解决方案2】:
对我来说,所有排列意味着比你产生的更多——0和3的大小也是如此。
假设数组没有重复项(如您的示例中所示),以下实现了这一点:
with recursive ar as (
select array[1,2,3] as ar
),
cte as (
select array[el] as els, array_remove( ar, el) as ar
from ar cross join
unnest(ar) as el
union all
select els || el, array_remove(ar, el)
from cte cross join
unnest(ar) as el
)
select * from cte;
Here 是一个 dbfiddle。如果这是您真正想要的,您可以过滤以删除大小 0 和 3。
如果你的数组有重复,你需要指定你想要的。