【发布时间】:2019-10-09 20:56:26
【问题描述】:
我正在尝试执行以下操作;假设我想在给定条件下将表分区为两个分区:
SELECT
userid,
ARRAY_AGG(userid) OVER (
PARTITION BY userid > 100
) arr,
AVG(userid) OVER (
PARTITION BY userid > 100
) avg
FROM users;
我会得到这个:
userid | arr | avg
--------+-----------------------------------------------------------+----------------------
46 | {46,23,69,92} | 57.5000000000000000
23 | {46,23,69,92} | 57.5000000000000000
69 | {46,23,69,92} | 57.5000000000000000
92 | {46,23,69,92} | 57.5000000000000000
552 | {552,506,575,621,644,667,690,759,713,782,828,460,483,529} | 629.2142857142857143
... | ... | ...
529 | {552,506,575,621,644,667,690,759,713,782,828,460,483,529} | 629.2142857142857143
一切都好,但是如果相反,对于 100 的用户 ID 中:
SELECT
userid,
CASE WHEN userid > 100
THEN ARRAY_AGG(userid) OVER (
PARTITION BY userid > 100
)
ELSE ARRAY_AGG(userid) OVER (
PARTITION BY userid -- OR userid > 100
-- PARTITION BY userid > 100 OR CURRENT_ROW
-- PARTITION BY userid > 100 OR userid = LAG(userid, 0) OVER ()
)
END arr
CASE WHEN userid > 100
THEN AVG(userid) OVER (
PARTITION BY userid > 100
)
ELSE AVG(userid) OVER (
PARTITION BY userid -- OR userid > 100
-- PARTITION BY userid > 100 OR CURRENT_ROW
-- PARTITION BY userid > 100 OR userid = LAG(userid, 0) OVER ()
)
END avg
FROM users;
上面所有注释的代码都是我一直在做的各种尝试。 我所拥有的最好的要么只是没有大于 100 的用户 ID,要么是所有用户 ID:
userid | arr | avg
--------+-----------------------------------------------------------+----------------------
23 | {23} | 23.0000000000000000
46 | {46} | 46.0000000000000000
69 | {69} | 69.0000000000000000
92 | {92} | 92.0000000000000000
552 | {552,506,575,621,644,667,690,759,713,782,828,460,483,529} | 629.2142857142857143
... | ... | ...
529 | {552,506,575,621,644,667,690,759,713,782,828,460,483,529} | 629.2142857142857143
有什么方法可以做我正在寻找的东西吗?我也尽量不使用 CTE,因为实际代码中的技术债务太多,仅使用 WITH 来适应它需要相当长的时间。
要清楚,这是预期的结果:
userid | arr | avg
--------+--------------------------------------------------------------|----------------------
23 | {23,552,506,575,621,644,667,690,759,713,782,828,460,483,529} | 588.6000000000000000
46 | {46,552,506,575,621,644,667,690,759,713,782,828,460,483,529} | 590.1333333333333334
69 | {69,552,506,575,621,644,667,690,759,713,782,828,460,483,529} | 591.6666666666666667
92 | {92,552,506,575,621,644,667,690,759,713,782,828,460,483,529} | 593.2000000000000000
552 | {552,506,575,621,644,667,690,759,713,782,828,460,483,529} | 629.2142857142857143
... | ... | ...
529 | {552,506,575,621,644,667,690,759,713,782,828,460,483,529} | 629.2142857142857143
这是我一直在寻找的潜在未来内容的参考:nested window functions(但目前尚未实现,截至 Postgresql-11)
编辑:最后但同样重要的是,条件是占位符!它可能与用户 ID 相关,也可能不相关,这里只是为了举例,它可能是
CUME_DIST() OVER (
PARTITION BY x -- OR CURRENT_USERID
)
【问题讨论】:
标签: sql postgresql partitioning window-functions