获取表的 ID 及其模尊重 Postgres 中同一表中的总行数

Posted

技术标签:

【中文标题】获取表的 ID 及其模尊重 Postgres 中同一表中的总行数【英文标题】:Get the ID of a table and its modulo respect the total rows in the same table in Postgres 【发布时间】:2021-08-18 10:58:34 【问题描述】:

在尝试将一些数据映射到表时,我想获取表的 ID 及其模数,以考虑同一表中的总行数。例如,给定这张表:

id
--
 1
 3
10
12

我想要这个结果:

id | mod
---+----
 1 |   1    <-  1 mod 4
 3 |   3    <-  3 mod 4
10 |   2    <- 10 mod 4
12 |   0    <- 12 mod 4

有没有一种简单的方法可以动态地实现这一点(例如,不计算手头上的行数或以原子方式进行)?

到目前为止,我已经尝试过这样的事情:

SELECT t1.id, t1.id % COUNT(t1.id) mod FROM tbl t1, tbl t2 GROUP BY t1.id;

这可行,但您必须拥有 GROUP BYtbl t2,否则它会为 mod 列返回 0,这是有道理的,因为我认为它通过将表自身相乘来工作,因此每个 ID 都会获得完整的集合桌子。我想对于足够小的表来说这是可以的,但我可以看到这对于更大的表来说是如何成为问题的。

编辑:找到另一种黑客方式:

WITH total AS (
    SELECT COUNT(*) cnt FROM tbl
)

SELECT t1.id, t1.id % t2.cnt mod FROM tbl t1, total t2

它类似于上一个查询,但它将乘法“折叠”为具有上一个计数的单行。

【问题讨论】:

【参考方案1】:

可以使用COUNT()窗口函数:

SELECT id, 
       id % COUNT(*) OVER () mod 
FROM tbl;

我确信优化器足够聪明,只计算一次窗口函数的结果。

请参阅demo。

【讨论】:

谢谢!它完美地工作。调查您的解决方案让我了解了我不知道它们存在的window functions,并且根据文档This is comparable to the type of calculation that can be done with an aggregate function. But unlike regular aggregate functions, use of a window function does not cause rows to become grouped into a single output row,这是我的确切问题。

以上是关于获取表的 ID 及其模尊重 Postgres 中同一表中的总行数的主要内容,如果未能解决你的问题,请参考以下文章

Postgres:更新所有表的主键序列

如何在 jpa 查询中调用 postgres position() 函数

ruby 将表的id重置为在rails中的postgres中开始

在 Postgres 上加入许多表的解决方案

对于多个表的循环postgres

如何使用 Postgres 中 CSV 文件中的值更新选定的行?