1

enter image description here

 $: select id from vehicles limit 5 offset 45
  -- Returns 

  -- 735
  -- 736
  -- 737
  -- 738
  -- 739

 $: select id, state from vehicles limit 5 offset 45;
  -- Returns

  -- 1381 | new
  -- 1327 | new
  -- 1304 | new
  -- 1382 | new
  -- 1317 | new

Even without adding any ordering/grouping, What could possibly be the reason why I am getting different set of records in my Postgresql when I added another column with 'id'?

PostgreSQL Ver - 12.6

6
  • I can't understand what you're talking about from your post.... Commented Dec 15, 2023 at 8:44
  • 1
    @JasonGoemaat OP likely expects the same 5 rows from both queries, only with additional column from the second one. Adding the column changes which 5 rows they're getting, which is somewhat counter-intuitive. Commented Dec 15, 2023 at 8:52
  • 1
    I can't disagree with the thread getting closed - both the SQL standard and PostgreSQL-specific aspect has been covered in the threads listed. The one feature that would potentially differentiate this thread from those would be the path from order-by-less order breaking pagination (aim indicated by the use of limit+offset), to reliable sampling. Still, unless OP comes back to clarify that's in fact the intention and edits it in, it would be a questionable moderation practice for a 3rd party to alter/expand the scope of the question based on guesses. Commented Dec 15, 2023 at 12:44
  • Even without adding any ordering Why do you expect an order when you don't ask for any order? Commented Dec 15, 2023 at 15:43
  • @FrankHeikens Because, selecting a single column has some kind of ordering, and I think it is reasonable to expect the same set of records if we added an additional column as well. Commented Dec 16, 2023 at 19:09

1 Answer 1

3

Limit 5 offset 45 you're using effectively gives you accidental 5 rows unless you add an order by - without it the order is not guaranteed. PostgreSQL is free to fetch rows in any order it wants and write them in any order it wants. Even if you cluster by an index, forcibly rewriting a table to follow an order implied by a certain index, the choice how to read it back to you remains arbitrary, unless you specify the order by clause. From the doc:

If sorting is not chosen, the rows will be returned in an unspecified order. The actual order in that case will depend on the scan and join plan types and the order on disk, but it must not be relied on. A particular output ordering can only be guaranteed if the sort step is explicitly chosen.

You can experience ordered reads and grow to expect some default sorting behaviour, but unless you use an order by those are pretty much accidental and you can't rely on them keeping their order in the future.


If what you were after is in fact some kind of random 5 rows, but in a reliable and stable manner, I don't think you can achieve that easily. You'd have to order by everything in a cte/subquery to get a stable input, setseed() and then order by random() before cutting out your limit 5 offset 45.

This would sort of emulate the tablesample clause:

select id, state 
from vehicles tablesample system(1) repeatable(.2) 
limit 5 offset 45;

Even with a seed specified in repeatable (or setseed()) neither is truly repeatable: if the table changes between statements you will no longer get the same sample.

Sign up to request clarification or add additional context in comments.

4 Comments

Right! Random suggests a different order for each query. Perhaps accidental is a better description.
@Andomar That's the word I've been looking for, thanks. Random, but unreliably random.
Accident implies an incident has happened. Perhaps arbitrary is even better?
@jarlh Hey, why not both. I've added that in as well. Accidental won with random because the latter could misleadingly suggest different each time. This one doesn't win with the previous champion but scores enough to get an honorable mention.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.