Đây là giải pháp của tôi bằng cách sử dụng WINDOW functions
. Tôi đã sử dụng lag
và lead
chức năng. Cả hai đều trả về một giá trị từ một cột từ một hàng được bù đắp từ hàng hiện tại. lag
quay lại và lead
tiếp theo trong phần bù đắp.
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)
Phiên bản đơn giản hóa:
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';
Những điểm chính
-
= ANY()
không cần thiết, hàm window trả về một giá trị duy nhất - một số trường thừa trong truy vấn con
- không cần sắp xếp theo cột, mà bạn
PARTITION BY
- ORDER BY áp dụng trong vòng phân vùng - Không sử dụng các mã nhận dạng chữ hoa và chữ thường hỗn hợp mà không có trích dẫn, điều đó chỉ dẫn đến sự nhầm lẫn. (Tốt hơn hết:không sử dụng số nhận dạng chữ hoa và chữ thường hỗn hợp trong PostgreSQL đã từng )