如何在PostgreSQL中创建一个字/字符串的所有可能字谜的列表。
例如,如果字符串是“行为”,那么所希望的输出应为:
行为,ATC,CTA,猫,TAC,TCA
我有一个表“tbl_words”其中包含的单词万元。
然后,我要检查/搜索唯一有效的话在我的数据库表从这个字谜名单。
从上面字谜的列表,例如有效的词是:行为,猫。
有没有办法做到这一点?
更新1:
我需要这样的输出:(所有置换给定字)
任何想法 ??
查询生成设置3个元素的所有排列:
with recursive numbers as (
select generate_series(1, 3) as i
),
rec as (
select i, array[i] as p
from numbers
union all
select n.i, p || n.i
from numbers n
join rec on cardinality(p) < 3 and not n.i = any(p)
)
select p as permutation
from rec
where cardinality(p) = 3
order by 1
permutation
-------------
{1,2,3}
{1,3,2}
{2,1,3}
{2,3,1}
{3,1,2}
{3,2,1}
(6 rows)
修改最终的查询,生成一个给定的单词的字母排列的:
with recursive numbers as (
select generate_series(1, 3) as i
),
rec as (
select i, array[i] as p
from numbers
union all
select n.i, p || n.i
from numbers n
join rec on cardinality(p) < 3 and not n.i = any(p)
)
select a[p[1]] || a[p[2]] || a[p[3]] as result
from rec
cross join regexp_split_to_array('act', '') as a
where cardinality(p) = 3
order by 1
result
--------
act
atc
cat
cta
tac
tca
(6 rows)
这里是一个解决方案:
with recursive params as (
select *
from (values ('cata')) v(str)
),
nums as (
select str, 1 as n
from params
union all
select str, 1 + n
from nums
where n < length(str)
),
pos as (
select str, array[n] as poses, array_remove(array_agg(n) over (partition by str), n) as rests, 1 as lev
from nums
union all
select pos.str, array_append(pos.poses, nums.n), array_remove(rests, nums.n), lev + 1
from pos join
nums
on pos.str = nums.str and array_position(pos.rests, nums.n) > 0
where cardinality(rests) > 0
)
select distinct pos.str , string_agg(substr(pos.str, thepos, 1), '')
from pos cross join lateral
unnest(pos.poses) thepos
where cardinality(rests) = 0
group by pos.str, pos.poses;
这是相当棘手,特别是当有反复字母的字符串中。这里采用的方法生成的数字从1到n,其中n是串的长度的所有排列。然后使用这些为指标从原来的字符串中提取的字符。
这些谁热衷会发现,这里使用select distinct
与group by
。这似乎是,以避免产生重复的字符串最简单的方法。