Я пытаюсь сделать следующее;скажем, я хочу разделить таблицу на два раздела при заданном условии:
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
Все хорошо, но что, если вместо этого, дляuserids <100, я хотел бы включить каждый userid с единицами> 100:
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 или все идентификаторы:
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
Вот справочник по потенциальным будущим вещам, на которые я смотрел: вложенные оконные функции (но на данный момент не реализованоPostgresql-11)
РЕДАКТИРОВАТЬ: И последнее, но не менее важное, условие является заполнителем! он может или не может быть привязан к идентификаторам пользователей, он используется здесь только для примера, это могло быть
CUME_DIST() OVER (
PARTITION BY x -- OR CURRENT_USERID
)