【问题标题】:All Permutations of an Array数组的所有排列
【发布时间】:2020-10-12 19:24:02
【问题描述】:

我也有与此处发布的相同的问题,但我很好奇如何在 PostgreSQL 方言中实现这一点 - Presto SQL - How can i get all possible combination of an array?

基本上来自一个看起来像 [1,2,3] 的数组,我正在寻找的结果是

[1]
[2]
[3]
[1,2]
[1,3]
[2,1]
[2,3]
[3,1]
[3,2]

如何在 Postgres 方言中实现这一点?

非常感谢。

【问题讨论】:

标签: 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。

    如果你的数组有重复,你需要指定你想要的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-05-03
      • 2012-04-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-27
      相关资源
      最近更新 更多