Wählen Sie die nächsten und vorherigen Zeilen aus

11

Ich habe folgende Tabelle:

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

Ich zeige die Liste mit der folgenden Abfrage an:

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

SELECT * FROM post where id=3Wie kann ich dann angesichts des durch id (dh ) ausgewählten Beitrags den nächsten und den vorherigen Beitrag abrufen?

Alice
quelle
1
Wenn Sie keine WHEREKlausel haben, geben Sie alle Zeilen aus der Tabelle zurück. Es gibt keine nächsten oder vorherigen. Könnten Sie es etwas besser erklären?
Dekso
@dezso Sorry, ich habe den Beitrag bearbeitet
Alice

Antworten:

15

Wenn Sie die Fensterfunktionen von PostgreSQL verwenden , sollten Sie speziell LAGund LEADin der Lage sein, die vorherigen und nächsten Einträge in Ihrer Tabelle anzuzeigen.

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);

Eine Demo finden Sie hier: http://sqlfiddle.com/#!15/9fd7a/8

bma
quelle
1
Und sollte es nicht eine im ORDER BYInneren geben OVER (...)?
Ypercubeᵀᴹ
1
Richtig, ich habe das ORDER BYin der OVER()Klausel verpasst . Ich habe entsprechend bearbeitet. Vielen Dank!
BMA
1
@ypercube: Möglicherweise interessiert Sie das, 3 IN (id, prev, next)in das 3 = ANY('{id, prev, next}')intern umgeschrieben wird . EXPLAIN ANALYZE enthüllt es.
Erwin Brandstetter
1
@bma: Nun, letztendlich wird jeder dieser Ausdrücke in eine Liste von OR-Ausdrücken aufgelöst. Vielleicht geht der 9.3.1-Planer in diesem Prozess noch einen Schritt weiter. Ich habe mit der neuesten Version nicht erneut getestet.
Erwin Brandstetter
2
Wow das 3 in (id, prev, next)bläst mich um, ich wünschte ich wüsste das schon mal :)
Davos