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
;
Резултат:
<предварителен str | str
-----+-----
W | T
W | F
W | !
T | F
T | !
F | !
(6 rows)
За съжаление не мога да намеря начин да избегна константата с двоен низ. (но цялото нещо може да бъде пакетирано във функция) Ако няма дублиращи се знаци (или искате да ги потиснете), можете да направите anti-join на str вместо на idx.
АКТУАЛИЗАЦИЯ (подсказка от ypercube) Изглежда, че OP иска низовете да бъдат свързани. Така да бъде::
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
;
Резултати:
results
---------
WT
WF
W!
TF
T!
F!
(6 rows)
АКТУАЛИЗАЦИЯ2:(тук идва рекурсивното...)
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
;
Резултати 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)