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 在递归查询中找到所有可能的组合(排列)的主要内容,如果未能解决你的问题,请参考以下文章