:
上記の例のテーブルと私はバックのような何かを得ることを期待する
20
の所望の長さを考えると
id | text
----------------
1 | hello
2 | world
WITH RECURSIVE recCte (sentence, length) AS
(
--recursive seed
SELECT
CAST("text" AS VARCHAR(200)) as sentence,
1 as length
FROM (SELECT "text" FROM test.fragments ORDER BY random() LIMIT 1)frag
UNION ALL
--recursive term
SELECT
CAST(recCTE.sentence || ' ' || frag.text as VARCHAR(200)),
recCTE.length + 1
FROM
reccte, (SELECT "text" from test.fragments ORDER BY random() LIMIT 1)frag
WHERE recCTE.length <= 20 --Sentence word length
)
--Select the full sentence made
SELECT sentence FROM recCTE WHERE length = 20;
これは少し関わっていますが、完璧ですあなたのニーズに合わせて再帰CTEクエリは、3つの部分で構成されています。
- 再帰的なシード - これは、非再帰的なクエリの部分です。これはクエリの出発点です。私たちはテーブルからランダムな単語を1つだけ取ります。
- 再帰的な用語 - これは再帰的なクエリの部分です。それはそれ自身を
...FROM recCTE ...
と呼んでいます。再び、テーブルからランダムに1つの単語をつかみ、それを文章の上に貼り付けます。これを実行している間、私たちは反復の深さを追跡し、20回のループの後に停止することができます。
- 再帰的なCTEから完全な文を選択するための最後のselect文。各繰り返しはレコードを作成するので、20にしたレコードを取得するだけです。文の長さを変更するには、再帰的CTEおよび最終的なSelect文で「20」を変更します。文字の長さを使用したバージョンを追加する
製作中:
我々はフラグメントテーブルからランダムなテキストを取得するためにORDER BY random() LIMIT 1
を使用する必要があるためこれは少しトリッキーですが、ORDER BY
をすることはできません再帰CTEではLIMIT
です。だから、正確に20文字を得ることは難しいですが、...私たちはかなり近いある、< = 20を得ることができます:
WITH RECURSIVE recCte (sentence, length) AS
(
SELECT
CAST("text" AS VARCHAR(200)) as sentence,
length("text") as length
FROM (SELECT "text" FROM test.fragments ORDER BY random() LIMIT 1)frag
UNION ALL
SELECT
CAST(cte.sentence || ' ' || frag.text as VARCHAR(200)),
cte.length + 1 + length(frag.text)
FROM
reccte cte, (SELECT text FROM test.fragments ORDER BY random() LIMIT 1) frag
WHERE
length(frag.text) < (20-cte.length)
AND cte.length <= 20 --Sentence word length
)
SELECT sentence, length FROM recCTE ORDER BY length DESC LIMIT 1;
大きな変化をここで文字長を計算し、中にこの制限を追加するLength
フィールドを変更します再帰的項の句のWHERE
。最後に、ORDER BY length DESC
でcteのレコードを文字の長さでソートし、LIMIT 1
を使って作成した最大のものを取得します。
恐ろしい!私はそれが再帰的なクエリであると考えましたが、私は実装上失われました。完全な答えをありがとう。 –