これは、WINDOW functions
を使用した私のソリューションです。 。 lag
を使用しました およびlead
関数。どちらも、現在の行からオフセットされた行の列から値を返します。 lag
戻ってlead
次にオフセットに進みます。
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)
簡略版:
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';
主なポイント
-
= ANY()
必要ない場合、ウィンドウ関数は単一の値を返します - サブクエリのいくつかの冗長フィールド
- 列で並べ替える必要はありません。
PARTITION BY
-ORDERBYは内に適用されます パーティション - 引用符なしで大文字と小文字が混在する識別子を使用しないでください。混乱を招くだけです。 (さらに良い方法:PostgreSQLでは大文字と小文字が混在する識別子を使用しないでください )