Dies ist meine Lösung mit WINDOW functions . Ich habe den lag verwendet und lead Funktionen. Both gibt einen Wert aus einer Spalte aus einer Zeile zurück, die von der aktuellen Zeile versetzt ist. lag geht zurück und lead geht als nächstes in den Offset.
SELECT tokcat.text
FROM (
SELECT text, category, chartype, lag(category,1) OVER w as previousCategory, lead(category,1) OVER w as nextCategory
FROM token t, textBlockHasToken tb
WHERE tb.tokenId = t.id
WINDOW w AS (
PARTITION BY textBlockId, sentence
ORDER BY textBlockId, sentence, position
)
) tokcat
WHERE 'NAME' = ANY(previousCategory)
AND 'NAME' = ANY(nextCategory)
AND 'NAME' <> ANY(category)
Vereinfachte Version:
SELECT text
FROM (
SELECT text
,category
,lag(category) OVER w as previous_cat
,lead(category) OVER w as next_cat
FROM token t
JOIN textblockhastoken tb ON tb.tokenid = t.id
WINDOW w AS (PARTITION BY textblockid, sentence ORDER BY position)
) tokcat
WHERE category <> 'NAME'
AND previous_cat = 'NAME'
AND next_cat = 'NAME';
Wichtige Punkte
= ANY()nicht benötigt wird, gibt die Fensterfunktion einen einzelnen Wert zurück- einige redundante Felder in der Unterabfrage
- Sie müssen nicht nach Spalten ordnen, die Sie
PARTITION BYverwenden - ORDER BY gilt innerhalb Partitionen - Verwenden Sie keine Groß-/Kleinschreibung ohne Anführungszeichen, das führt nur zu Verwirrung. (Noch besser:Verwenden Sie in PostgreSQL niemals Bezeichner mit gemischter Groß-/Kleinschreibung )