2015-10-22 64 views
1

我有一個查詢,我想闖入大小爲200的「塊」,並返回每個「塊」的開始ID和結束ID。Sql範圍組開始和結束編號

例子:

select t.id 
from t 
where t.x = y --this predicate will cause the ids to not be sequential 

如果例子是,我試圖闖入「塊」我願意返回查詢:

(第1號,第200號),(第201 ID,第400個ID)...(最終範圍ID的開始,範圍ID的結尾)

編輯:對於最終範圍,如果它不是完整的200行,它應該仍然在查詢中提供最終的ID。

有沒有辦法只用SQL來做到這一點,還是我不得不求助於類似於分頁實現的應用程序處理和/或多個查詢?

如果有一種方法可以在SQL中執行此操作,請提供一個示例。

+0

[OFFSET ... FETCH ...](HTTP:// WWW .postgresql.org/docs/current/static/sql-select.html) – lad2025

+1

@ lad2025我從來沒有使用這些關鍵字。謝謝我會看看我能想出什麼,如果仍有問題,請更新我的問題。 – rocktheartsm4l

+0

我還不清楚你是否想要一個數字列表'begin;結束;存在;結尾;'或成對'(開始,結束)'或範圍內'ids'的列表'(開始,結束)' –

回答

2

嗯,我認爲最簡單的方法是使用row_number()

select id 
from (select t.*, row_number() over (order by id) as seqnum 
     from t 
     where t.x = y 
    ) t 
where (seqnum % 200) in (0, 1); 

編輯:

根據您的意見:

select min(id) as startid, max(id) as endid 
from (select t.*, 
      floor((row_number() over (order by id) - 1)/200) as grp 
     from t 
     where t.x = y 
    ) t 
group by grp; 
+0

非常接近我正在尋找的東西,如果我在應用程序中編寫了一些邏輯來解釋這些結果,它就會起作用。一個理想的解決方案會得到和你一樣的結果,但每行都會有(開始,結束)。另外,如果最後的範圍不是完整的200,它應該提供我查詢中的最後一個ID;我沒有明確地在我的OP中定義這個。 – rocktheartsm4l

+1

只需添加'OR seqnum =(SELECT count(*)FROM table)'以包含最後一個ID。 –

+0

最後的編輯提供了我需要的確切結果。謝謝。在接受之前測試效率與其他答案。 – rocktheartsm4l

1

L左,R爲右

WITH cte AS (
    SELECT 
      t.id, 
      row_number() over (order by id) as seqnum 
    FROM Table t 
    WHERE t.x = y 
) 
SELECT L.id as start_id, COALESCE(R.id, (SELECT MAX(ID) FROM cte)) as end_id 
FROM cte L 
LEFT JOIN cte R 
     ON L.seqnum = R.seqnum - 199 
WHERE L.seqnum % 200 = 1 

SqlFiddleDemo 濾波僅偶數和的4

塊查看如何R.seqnum - 199爲大小的塊200

+0

讓這個工作很困難。 'SELECT'的語法錯誤指的是... COALESC(R.id,SELECT MAX(id)FROM ... – rocktheartsm4l

+0

給予秒,我將準備一個sqlfiddle –

+0

我拼錯'COALESCE'我還包括數據較小的樣本。 –

相關問題