I have a table in Postgres
id | title | ….. |
---|---|---|
1 | title1 | ….. |
2 | title2 | ….. |
3 | title1 | ….. |
4 | title13 | ….. |
5 | title4 | ….. |
6 | title7 | ….. |
7 | title1 | ….. |
8 | title1 | ….. |
9 | title53 | ….. |
10 | title11 | ….. |
11 | title1 | ….. |
and I have a Golang app that uses a GORM as ORM
I need to select columns id and title, where title should be distinct, and it should have key-set pagination by id. For example, if page has side 3, I should select
1 – title1
2 – title2
4 – title13
2d page should be
5 – title4
6 – title7
9 – title53
Any thoughts are welcome, even row sql
2
Answers
You can first select all unique titles as a set, then get their id from your table. For example:
EDIT: if you have large amount of data in this table you can further optimize the query to limit and skip unique titles first then get their id:
Assuming
id
isUNIQUE NOT NULL
, this achieves your objective:fiddle
Notably,
DISTINCT ON
cannot be combined with anORDER BY
that disagrees on the same query level. See:But the intermediate step with
DISTINCT ON
disables direct index support. An index with leadingtitle
field may still be used, but the whole table (or just index in an index-only scan) has to be processed for every query. Not actually "key-set pagination".If at all possible, create a
MATERIALIZED VIEW
with an index onid
. That is, you can afford to reuse the generated result for enough time before having to refresh.The optional
INCLUDE
clause enables index-only scans (after runningVACUUM
, orVACUUM ANALYZE
on it, unlessautovacuum
has kicked in.)Depending on data distribution the
DISTINCT ON
query might be optimized further. See:The query now is just: