获取 table 的 ID 及其模数尊重 Postgres 中相同 table 中的总行数
Get the ID of a table and its modulo respect the total rows in the same table in Postgres
在尝试将一些数据映射到 table 时,我想获取 table 的 ID 及其模数,以考虑同一 table 中的总行数。例如,给定此 table:
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 BY
和 tbl t2
,否则 returns 0 用于 mod
列,这是有道理的,因为我认为它通过乘法来工作table 本身,因此每个 ID 都会得到一整套 table。我想对于足够小的 tables 这没关系,但我可以看到这对于更大的 tables 是如何成为问题的。
编辑: 找到另一种 hack-ish 方式:
WITH total AS (
SELECT COUNT(*) cnt FROM tbl
)
SELECT t1.id, t1.id % t2.cnt mod FROM tbl t1, total t2
它与之前的查询类似,但它将乘法“折叠”为具有之前计数的一行。
您可以使用COUNT()
window函数:
SELECT id,
id % COUNT(*) OVER () mod
FROM tbl;
我确信优化器足够聪明,可以只计算一次 window 函数的结果。
参见demo。
在尝试将一些数据映射到 table 时,我想获取 table 的 ID 及其模数,以考虑同一 table 中的总行数。例如,给定此 table:
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 BY
和 tbl t2
,否则 returns 0 用于 mod
列,这是有道理的,因为我认为它通过乘法来工作table 本身,因此每个 ID 都会得到一整套 table。我想对于足够小的 tables 这没关系,但我可以看到这对于更大的 tables 是如何成为问题的。
编辑: 找到另一种 hack-ish 方式:
WITH total AS (
SELECT COUNT(*) cnt FROM tbl
)
SELECT t1.id, t1.id % t2.cnt mod FROM tbl t1, total t2
它与之前的查询类似,但它将乘法“折叠”为具有之前计数的一行。
您可以使用COUNT()
window函数:
SELECT id,
id % COUNT(*) OVER () mod
FROM tbl;
我确信优化器足够聪明,可以只计算一次 window 函数的结果。
参见demo。