PostgreSQL 在递归查询中找到所有可能的组合(排列)

Posted

技术标签:

【中文标题】PostgreSQL 在递归查询中找到所有可能的组合(排列)【英文标题】:PostgreSQL find all possible combinations (permutations) in recursive query 【发布时间】:2015-08-11 12:25:57 【问题描述】:

输入是一个长度为“n”的数组。我需要生成数组元素的所有可能组合,包括输入数组中元素较少的所有组合。

IN: j='A, B, C ..'
OUT: k='A, AB, AC, ABC, ACB, B, BA, BC, BAC, BCA..' 

重复,所以AB BA..

我尝试过这样的事情:

WITH RECURSIVE t(i) AS (SELECT * FROM unnest('A,B,C'::text[])) 
,cte AS (
    SELECT i AS combo, i, 1 AS ct 
    FROM t 
  UNION ALL 
    SELECT cte.combo || t.i, t.i, ct + 1 
    FROM cte 
    JOIN t ON t.i > cte.i
) 
SELECT ARRAY(SELECT combo FROM cte ORDER BY ct, combo ) AS result;

它正在生成没有重复的组合......所以我需要以某种方式修改它。

【问题讨论】:

你试过什么?您必须在 Postgres 中执行此操作吗?您可以使用 pl/PGSQL 或其他过程语言吗?一定要使用数组吗? 您只想要长度为 1 到 3 的字符串吗? 输入是可变的,因此它应该对数组中的所有元素进行组合.. 似乎是***.com/q/30471120/398670的主要转贴 您是否查找过公认的算法来生成组合?也许如果你确定了你想怎么做,然后尝试在 SQL 中实现它,你会得到更好的结果.. 【参考方案1】:

在递归查询中,搜索表中在迭代中使用的术语被删除,然后对剩余的记录重复查询。在您的情况下,这意味着一旦您处理了第一个数组元素(“A”),它就不再可用于数组元素的进一步排列。要让那些“使用过的”元素重新加入,您需要与递归查询中的数组元素表交叉连接,然后过滤掉当前排列中已使用的数组元素 (position(t.i in cte.combo) = 0) 和停止迭代的条件(ct <= 3)。

WITH RECURSIVE t(i) AS (
  SELECT * FROM unnest('A,B,C'::char[])
), cte AS (
     SELECT i AS combo, i, 1 AS ct 
     FROM t 
   UNION ALL 
     SELECT cte.combo || t.i, t.i, ct + 1 
     FROM cte, t
     WHERE ct <= 3
       AND position(t.i in cte.combo) = 0
) 
SELECT ARRAY(SELECT combo FROM cte ORDER BY ct, combo) AS result;

【讨论】:

这是一个 SQL Fiddle:sqlfiddle.com/#!15/9eecb7db59d16c80417c72d1e1f4fbf1/497.

以上是关于PostgreSQL 在递归查询中找到所有可能的组合(排列)的主要内容,如果未能解决你的问题,请参考以下文章

访问 2010 递归数据

[转]PostgreSQL 递归查询一例

PostgreSQL递归查询示例

postgresql with递归

Postgresql:查询返回不正确的数据

java 找到一节点的所有子节点 是否得递归实现?