Sie könnten einen rekursiven CTE für diesen Einsatz:
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;
Dies ist ein wenig beteiligt, aber es ist perfekt für Ihre Bedürfnisse. Eine rekursive CTE-Abfrage besteht aus drei Teilen.
- Der rekursive Seed - Dies ist der Teil der Abfrage, die nicht rekursiv ist. Es ist der Ausgangspunkt für die Abfrage. Wir greifen nur ein zufälliges Wort aus der Tabelle.
- Der rekursive Ausdruck - Dies ist der Teil der Abfrage, der rekursiv ist. Es bezieht sich auf sich selbst
...FROM recCTE ...
. Wir greifen wieder zufällig ein Wort aus dem Tisch und kleben es auf den Satz. Während wir dies tun, verfolgen wir, wie tief wir in den Iterationen sind, so dass wir nach 20 Schleifen anhalten können.
- Die endgültige Select-Anweisung, um den vollständigen Satz aus dem rekursiven CTE auszuwählen. Jede Iteration erstellt einen Datensatz, so dass wir uns den Datensatz nehmen, der ihn auf 20 gebracht hat. Ändern Sie "20" im rekursiven CTE und die finale Select-Anweisung, um die Länge des Satzes zu ändern.
editting eine Version hinzuzufügen, die Zeichenlänge verwendet:
Dies ist ein wenig komplizierter, weil wir ORDER BY random() LIMIT 1
zu bekommen einen zufälligen Text aus der Fragmente Tabelle verwenden, aber Sie können nicht ORDER BY
und LIMIT
in einem rekursiven CTE. Also immer genau 20 Zeichen ist schwierig, aber .. können wir < = 20 erhalten, die ganz in der Nähe ist:
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;
Die großen Änderungen hier ändern sich die Length
Feld die Zeichenlänge zu berechnen und diese Einschränkung hinzuzufügen, in die WHERE
Klausel des rekursiven Terms. Schließlich wir ORDER BY length DESC
, um die CTE-Datensätze nach Zeichenlänge zu sortieren, und LIMIT 1
, um die größte, die wir durch die Iterationen erstellt zu greifen.
Super! Ich dachte, es wäre etwas in einer rekursiven Abfrage, aber ich war bei der Implementierung verloren. Danke für die ausführliche Antwort. –