Dit is mijn oplossing met behulp van WINDOW functions
. Ik gebruikte de lag
en lead
functies. Beide retourneert een waarde uit een kolom uit een rij in offset ten opzichte van de huidige rij. lag
gaat terug en lead
gaat als volgende in de 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)
Vereenvoudigde versie:
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';
Belangrijkste punten
= ANY()
is niet nodig, de vensterfunctie retourneert een enkele waarde- enkele overbodige velden in de subquery
- het is niet nodig om op kolommen te bestellen, die u
PARTITION BY
- de ORDER BY geldt binnen partities - Gebruik geen hoofdletter-ID's zonder aanhalingstekens, dit leidt alleen maar tot verwarring. (Beter nog:gebruik geen hoofdletter-ID's in PostgreSQL ooit )