2017-04-09 52 views
1

我想在postgresql中使用一個查詢,它可以根據用於某些分頁的起始記錄ID獲取前一個和下一個X數量的記錄。下一個或上一個只有1個並不難,但那不是我所需要的。SQL - 獲取下一個和上一個X記錄

我發現了一些接近的查詢,但我對PostgreSQL查詢並不瞭解,無法完成這些類型的複雜查詢。

下面這個查詢我嘗試過並改變了工作,但是似乎只帶回了上一個和下一個ID的標識和全部的記錄。

但是我需要能夠給出一個起點,例如在WHERE子句中提供一個ID,並且如果它們存在,則只能獲得10條上一條和10條下一條記錄。這是可能在SQL單獨做?

SELECT 
    m.med_id AS id, 
    coalesce(
     LEAD(m.med_id) OVER (ORDER BY m.med_id DESC), 
     (select med.med_id from media as med order by med.med_id desc limit 1) 
) AS nextitemid, 
    coalesce(
     LAG(m.med_id) OVER (ORDER BY m.med_id DESC), 
     (select med.med_id from media as med order by med.med_id asc limit 1) 
) AS previtemid 
FROM media m 
WHERE m.post_type = 1 
ORDER BY m.med_id DESC LIMIT 20; 

任何幫助將不勝感激,它可以是任何類型的SQL解決方案,可以實現這一點。

我相信所希望的輸出將來自100個作爲查詢中提供的ID起點的50個項目的示例。

|previtemids|nextitemids| 
    49   51 
    48   52 
    47   53 
    46   54 
    45   55 
    44   56 
    43   57 
    42   58 
    41   59 
    40   60 

我走近了,但一直沒有能夠得到它在一個查詢。接近我的方案的答案比通用答案更有幫助。

+0

您想要列中的前10個和後10個記錄,或每個記錄的單獨行嗎? – Alex

+0

嗯好問題@亞歷克斯我會讀它從PHP到數組。也許列可能更容易? –

+0

您能否發佈您想要的輸出示例? – Alex

回答

0
with numbered as(
    select your_table.*, row_number() over(order by id) as rn from your_table 
) 
SELECT previous.id, next.id FROM 
(SELECT id, row_number() over(order by id) as inner_rn FROM numbered where rn between (select rn from numbered WHERE id = 12) - 5 and (select rn from numbered WHERE id = 12) -1) previous 
INNER JOIN 
(SELECT id, row_number() over(order by id) as inner_rn FROM numbered where rn between (select rn from numbered WHERE id = 12) + 1 and (select rn from numbered WHERE id = 12) + 5) next 
ON previous.inner_rn = next.inner_rn 

如果我正確理解你需要這個

這裏12 starting point providing an ID和5是一個和上一個X記錄

(注:例如,如果沒有10前一行,但有是10個下一行,並且你需要用NULL填充缺失的值,然後用FULL JOIN代替INNER JOIN

+0

所以這並沒有真正產生正確的結果。我的查詢接近我所需要的。只是沒有按預期工作。 –

+0

那麼你需要不同的兩列中的前一個和下一個xid? (如在你編輯的例子?) –

+0

我認爲這將是理想的 –

0

所以這就是如何完成的,我們用它來產生0-1000之間的100個隨機數字..

SELECT 
    trunc(random()*1000) AS x 
FROM generate_series(1,100); 

現在我們給了80的id,我們可以在這裏找到70-90的範圍。

SELECT * 
FROM (
    SELECT rank() OVER (ORDER BY x) AS dr, x 
    FROM (
    SELECT 
     trunc(random()*1000) AS x 
    FROM generate_series(1,100) 
) AS t 
) AS t 
WHERE dr BETWEEN 80-10 AND 80+10; 

dr | x 
----+----- 
70 | 702 
71 | 706 
72 | 718 
73 | 734 
74 | 751 
75 | 756 
76 | 774 
77 | 778 
78 | 805 
79 | 813 
80 | 829 
81 | 833 
82 | 839 
83 | 852 
84 | 853 
85 | 872 
86 | 884 
86 | 884 
88 | 892 
89 | 897 
90 | 905 
(21 rows) 

但我不會這樣做。我會通過傳遞一個id和所需的行來進行分頁。並且只允許前進。將以前的結果存儲在瀏覽器中。

相關問題