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 BY
verwenden - 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 )