To jest moje rozwiązanie wykorzystujące WINDOW functions
. Użyłem lag
i lead
Funkcje. Oba zwracają wartość z kolumny z wiersza w przesunięciu względem bieżącego wiersza. lag
wraca i lead
idzie dalej w przesunięciu.
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)
Wersja uproszczona:
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';
Główne punkty
= ANY()
nie jest potrzebne, funkcja window zwraca pojedynczą wartość- niektóre nadmiarowe pola w podzapytaniu
- nie ma potrzeby porządkowania według kolumn,
PARTITION BY
- ORDER BY obowiązuje w ciągu partycje - Nie używaj identyfikatorów z mieszaną wielkością liter bez cytowania, to tylko prowadzi do zamieszania. (Jeszcze lepiej:nie używaj mieszanych identyfikatorów wielkości liter w PostgreSQL kiedykolwiek )