set search_path='tmp';
WITH ztab AS (
SELECT idx as idx
, substring ( 'WTF!' FROM idx FOR 1) as str
FROM generate_series(1, char_length( 'WTF!' )) idx
)
SELECT t1.str, t2.str
FROM ztab t1
JOIN ztab t2 ON t2.idx > t1.idx
;
Výsledek:
str | str
-----+-----
W | T
W | F
W | !
T | F
T | !
F | !
(6 rows)
Bohužel nemohu najít způsob, jak se vyhnout dvojřetězcové konstantě. (ale celá věc by mohla být zabalena do funkce) Pokud neexistují žádné duplicitní znaky (nebo je chcete potlačit), můžete provést anti-join na str místo idx.
UPDATE (nápověda z ypercube) Zdá se, že OP chce, aby byly řetězce zřetězeny. Budiž::
WITH ztab AS (
SELECT idx as idx
, substring ( 'WTF!' FROM idx FOR 1) as str
FROM generate_series(1, char_length( 'WTF!' )) idx
)
SELECT t1.str || t2.str AS results
FROM ztab t1
JOIN ztab t2 ON t2.idx > t1.idx
;
Výsledky:
results
---------
WT
WF
W!
TF
T!
F!
(6 rows)
UPDATE2:(tady přichází ta rekurzivní věc...)
WITH RECURSIVE xtab AS (
WITH no_cte AS (
SELECT
1::int AS len
, idx as idx
, substring ( 'WTF!' FROM idx FOR 1) as str
FROM generate_series(1, char_length( 'WTF!' )) idx
)
SELECT t0.len as len
, t0.idx
, t0.str
FROM no_cte t0
UNION SELECT 1+t1.len
, tc.idx
, t1.str || tc.str AS str
FROM xtab t1
JOIN no_cte tc ON tc.idx > t1.idx
)
SELECT * FROM xtab
ORDER BY len, str
-- WHERE len=2
;
Výsledky 3:
len | idx | str
-----+-----+------
1 | 4 | !
1 | 3 | F
1 | 2 | T
1 | 1 | W
2 | 4 | F!
2 | 4 | T!
2 | 3 | TF
2 | 4 | W!
2 | 3 | WF
2 | 2 | WT
3 | 4 | TF!
3 | 4 | WF!
3 | 4 | WT!
3 | 3 | WTF
4 | 4 | WTF!
(15 rows)