【问题标题】:PostgreSQL find all possible combinations (permutations) in recursive queryPostgreSQL 在递归查询中找到所有可能的组合(排列)
【发布时间】: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 的字符串吗?
  • 输入是可变的,因此它应该对数组中的所有元素进行组合..
  • 似乎是stackoverflow.com/q/30471120/398670的主要转贴
  • 您是否查找过公认的算法来生成组合?也许如果你确定了你想怎么做,然后尝试在 SQL 中实现它,你会得到更好的结果..

标签: sql postgresql combinations


【解决方案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;

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-06
  • 2014-02-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多