Chọn các hàng tiếp theo và trước đó


11

Tôi có bảng sau:

CREATE TABLE post (
  id            bigint primary key,
  thread_id     bigint,
  is_notice     boolean,
  title         text,
  content       text
)

Tôi hiển thị danh sách bằng cách sử dụng truy vấn sau:

SELECT * FROM post ORDER BY is_notice desc, thread_id desc, id

Sau đó, được đưa ra bài đăng được chọn bởi id (tức là SELECT * FROM post where id=3), làm cách nào để truy xuất các bài đăng tiếp theo và trước đó?


1
Vâng, không có một WHEREmệnh đề, bạn trả lại tất cả các hàng từ bảng, không có tiếp theo hoặc trước đó. Bạn có thể giải thích tốt hơn một chút?
dezso

@dezso Xin lỗi, tôi đã chỉnh sửa bài đăng
alice

Câu trả lời:


15

Sử dụng các Hàm cửa sổ của PostgreQuery , cụ thể LAGLEAD, sẽ có thể hiển thị cho bạn các mục trước và tiếp theo trong bảng của bạn.

select *
from (
    select  id, thread_id, is_notice, title, content,
            lag(id) over (order by is_notice desc, thread_id desc, id asc) as prev,
            lead(id) over (order by is_notice desc, thread_id desc, id asc) as next
    from post
    ) x
where 3 IN (id, prev, next);

Một bản demo có thể được tìm thấy ở đây: http://sqlfiddle.com/#!15/9fd7a/8


1
Và không nên có một ORDER BYbên trong OVER (...)?
ypercubeᵀᴹ

1
Đúng bạn, tôi đã bỏ lỡ ORDER BYcác OVER()điều khoản. Tôi đã chỉnh sửa tương ứng. Cảm ơn!
bma

1
@ypercube: Bạn có thể quan tâm 3 IN (id, prev, next)được viết lại thành 3 = ANY('{id, prev, next}')nội bộ. GIẢI THÍCH ANALYZE tiết lộ nó.
Erwin Brandstetter

1
@bma: Chà, cuối cùng, một trong hai biểu thức này được phân giải thành một danh sách các biểu thức ORed. Có thể, trình hoạch định 9.3.1 tiến thêm một bước trong quy trình này. Tôi đã không thử lại với phiên bản mới nhất.
Erwin Brandstetter

2
Wow 3 in (id, prev, next), tôi nghĩ rằng mình đã biết về điều đó trước đây :)
Davos
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.