2012-08-10 22 views
8

我在Postgres的以下查詢:奇怪的順序錯誤(它是一個錯誤嗎?)在Postgres的

SELECT * 
FROM "bookings" 
WHERE ("bookings".client_id = 50) 
ORDER BY session_time DESC 
LIMIT 20 OFFSET 0 

在第20位的紀錄是具有相同session_time到第21記錄。

該查詢返回20個結果,但是如果將結果與整個數據庫進行比較,查詢將返回第1個到第19個結果,第21個結果跳過第20個結果。

SELECT * 
FROM "bookings" 
WHERE ("bookings".client_id = 50) 
ORDER BY session_time DESC, id 
LIMIT 20 OFFSET 0 

但是我不知道如何發生這樣的錯誤:

這種查詢可以通過添加,「ID」的順序是固定的? postgres在使用偏移和限制時如何命令相同的字段?它是隨機的嗎?這是與postgres的錯誤?

+4

如果您需要確定性結果,您需要在您的訂單中包含一個唯一的聯繫斷路器。這與沒有'order by'完全相同,並期望結果按特定順序排序。沒有保證,他們會。 – 2012-08-10 15:30:49

+3

你指的是一種穩定的排序。穩定的排序在記錄具有匹配的鍵時按原始順序保存記錄。在SQL中絕對不需要穩定的排序。我不會依賴任何產品。正如馬丁所建議的那樣,使用另一列作爲決勝盤。 – 2012-08-10 15:32:37

+6

這是最肯定*不是*的錯誤 - 你問它只是'session_time'命令,並規劃者會給你最快的計劃,這樣做;它沒有假設你可能想要訂購的東西你沒有說明。爲了好玩,更新其中的一行(甚至是當前值)並執行沒有ORDER BY子句的SELECT。如果你想按照特定的順序進行操作,你需要指定。 – kgrittn 2012-08-10 15:54:18

回答

8

這不是一個錯誤。限制和偏移發生在排序之後,並且不確定哪些行在一種情況下與另一種情況下被選擇。一般而言,您希望擁有一個tiebreaker,以便您的訂購具有穩定性和確定性(即使我沒有限制或偏移問題以確保查詢在每次運行時都是相同的,我更願意使用唯一的tiebreaker)。

如果您正在進行分頁,請將主鍵或代理鍵添加到排序中作爲仲裁者。這真的是最好的方法。