Go语言 Postgres Select Distinct On(带键集分页)

bzzcjhmw  于 5个月前  发布在  Go
关注(0)|答案(2)|浏览(37)

我在Postgres订了桌位
| ID|标题|......这是什么?|
| --|--|--|
| 1 |标题1|......这是什么?|
| 2 |标题2|......这是什么?|
| 3 |标题1|......这是什么?|
| 4 |标题13|......这是什么?|
| 5 |标题4|......这是什么?|
| 6 |标题7|......这是什么?|
| 7 |标题1|......这是什么?|
| 8 |标题1|......这是什么?|
| 9 |标题53|......这是什么?|
| 10 |标题11|......这是什么?|
| 11 |标题1|......这是什么?|
我有一个Golang应用程序,它使用一个ORM作为ORM,
我需要选择列id和title,其中title应该是不同的,并且应该有按id的键集分页。
1 -标题1 2 -标题2 4 -标题13
2D页面应该是
5 -标题4 6 -标题7 9 -标题53
任何想法都是受欢迎的,甚至行SQL

0aydgbwb

0aydgbwb1#

您可以首先选择所有唯一的标题作为一个集合,然后从表中获取它们的id。例如:

WITH titles AS (
    SELECT DISTINCT title, id FROM my_table
)

SELECT my_table.id, my_table.title FROM my_table
JOIN titles ON titles.id = my_table.id
ORDER BY id -- or by other column
LIMIT 3
OFFSET 3

字符串
编辑:如果你在这个表中有大量的数据,你可以进一步优化查询,首先限制和跳过唯一的标题,然后获取它们的id:

WITH titles AS (
    SELECT DISTINCT title, id FROM my_table
    ORDER BY id
    LIMIT 3
    OFFSET 3
)

SELECT my_table.id, my_table.title, .... FROM my_table
JOIN titles ON titles.id = my_table.id

dluptydi

dluptydi2#

假设idUNIQUE NOT NULL,这就实现了你的目标:

WITH cte AS (
   SELECT DISTINCT ON (title)
          title, id
   FROM   tbl
   ORDER  BY title, id
   )
SELECT *
FROM   cte
ORDER  BY id
LIMIT  3
OFFSET 3;

字符串
fiddle
值得注意的是,DISTINCT ON不能与在同一查询级别上不一致的ORDER BY组合。请参阅:

  • PostgreSQL DISTINCT ON与不同的ORDER BY
  • 是否选择每个GROUP BY组中的第一行?

但是使用DISTINCT ON的中间步骤禁用了直接索引支持。仍然可以使用带有前导title字段的索引,但是必须为每个查询处理整个表(或者仅索引扫描中的索引)。实际上不是“键集分页”。
如果可能的话,在id上创建一个索引MATERIALIZED VIEW。也就是说,您可以在刷新之前重用生成的结果足够长的时间。

CREATE MATERIALIZED VIEW mv_tbl AS
SELECT DISTINCT ON (title)
       title, id
FROM   tbl
ORDER  BY title, id;

CREATE UNIQUE INDEX mv_tbl_uniq ON mv_tbl (id) INCLUDE (title);


可选的INCLUDE子句启用仅索引扫描(在其上运行VACUUMVACUUM ANALYZE之后,除非autovacuum已启动)。
根据数据分布情况,DISTINCT ON查询可能会进一步优化。请参阅:

  • 优化GROUP BY查询以检索每个用户的最新行

现在的查询只是:

SELECT *
FROM   mv_tbl
ORDER  BY id
LIMIT  3
OFFSET 3;

相关问题