查询 table 与 array_agg/median 的所有先前位置,LAST_10,LAST_50,不包括当前位置
Query table with array_agg/median of ALL previous positions, LAST_10, LAST_50, excluding current position
这是我发布的这个回答得很好的问题的变体 :
我有一个数据库 table 有:
id | date | position | name
--------------------------------------
1 | 2016-06-29 | 9 | Ben Smith
2 | 2016-06-29 | 1 | Ben Smith
3 | 2016-06-29 | 5 | Ben Smith
4 | 2016-06-29 | 6 | Ben Smith
5 | 2016-06-30 | 2 | Ben Smith
6 | 2016-06-30 | 2 | Tom Brown
7 | 2016-06-29 | 4 | Tom Brown
8 | 2016-06-30 | 2 | Tom Brown
9 | 2016-06-30 | 1 | Tom Brown
如何有效地查询 table 以便我可以使用 array_agg() 获取新列。
我已经尝试过以下查询,但是它非常慢而且错误,因为它没有按名称列对 previous_positions 进行分组:
SELECT runners.id AS runner_id,
btrim(regexp_replace(replace(upper(runners.name::text), '.'::text, ''::text), '[[:digit:]]'::text, ''::text, 'g'::text)) AS name,
runners.position_two,
(array_agg(runners.position_two) OVER w AS results
FROM runners
WINDOW w AS (PARTITION BY (btrim(regexp_replace(replace(upper(runners.name::text), '.'::text, ''::text), '[[:digit:]]'::text, ''::text, 'g'::text))) ORDER BY runners.id ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING);
我希望 table 输出看起来像这样
id | date | position | name | previous | med |med_20
----------------------------------------------------------------------
1 | 2016-06-29 | 9 | Ben Smith | {} | |
2 | 2016-06-29 | 1 | Ben Smith | {9} | 9 | 9
3 | 2016-06-29 | 5 | Ben Smith | {9,1} | 5 | 5
4 | 2016-06-29 | 6 | Ben Smith | {9,1,5} | 5 | 5
5 | 2016-06-30 | 2 | Ben Smith | {9,1,5,6} | 5.5 | 5.5
6 | 2016-06-30 | 2 | Tom Brown | {} | None | None
7 | 2016-06-29 | 4 | Tom Brown | {2} | 2 | 2
8 | 2016-06-30 | 2 | Tom Brown | {2,4} | 3 | 3
9 | 2016-06-30 | 1 | Tom Brown | {2,4,2} | 2 | 2
Postgres 没有 MEDIAN
的 built-in 聚合函数。但是,您可以使用 Postgres wiki. This snippet is also part of the ulib_agg user-defined library.
中提供的函数片段创建一个
创建后,您可以像 SUM
或 STRING_AGG
等具有类似 window
规范的任何聚合函数一样使用它。 Postgres 为您提供了为以逗号分隔的聚合函数指定多个 window
定义的选项。
因此,要获取前 20 条记录的 MEDIAN
,您的 window 可以定义为在此查询中。
SELECT
j.* , array_agg(position) over w as previous_positions,
median(position) over w_20 as med_20
FROM jockeys j
WINDOW w as
( partition by name ORDER BY id rows between
unbounded preceding and 1 preceding
),
w_20 as
( partition by name ORDER BY id rows between
20 preceding and 1 preceding
)
此外,如果您想截断小数位,您可以应用 ROUND
函数。
这是我发布的这个回答得很好的问题的变体
我有一个数据库 table 有:
id | date | position | name
--------------------------------------
1 | 2016-06-29 | 9 | Ben Smith
2 | 2016-06-29 | 1 | Ben Smith
3 | 2016-06-29 | 5 | Ben Smith
4 | 2016-06-29 | 6 | Ben Smith
5 | 2016-06-30 | 2 | Ben Smith
6 | 2016-06-30 | 2 | Tom Brown
7 | 2016-06-29 | 4 | Tom Brown
8 | 2016-06-30 | 2 | Tom Brown
9 | 2016-06-30 | 1 | Tom Brown
如何有效地查询 table 以便我可以使用 array_agg() 获取新列。
我已经尝试过以下查询,但是它非常慢而且错误,因为它没有按名称列对 previous_positions 进行分组:
SELECT runners.id AS runner_id,
btrim(regexp_replace(replace(upper(runners.name::text), '.'::text, ''::text), '[[:digit:]]'::text, ''::text, 'g'::text)) AS name,
runners.position_two,
(array_agg(runners.position_two) OVER w AS results
FROM runners
WINDOW w AS (PARTITION BY (btrim(regexp_replace(replace(upper(runners.name::text), '.'::text, ''::text), '[[:digit:]]'::text, ''::text, 'g'::text))) ORDER BY runners.id ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING);
我希望 table 输出看起来像这样
id | date | position | name | previous | med |med_20
----------------------------------------------------------------------
1 | 2016-06-29 | 9 | Ben Smith | {} | |
2 | 2016-06-29 | 1 | Ben Smith | {9} | 9 | 9
3 | 2016-06-29 | 5 | Ben Smith | {9,1} | 5 | 5
4 | 2016-06-29 | 6 | Ben Smith | {9,1,5} | 5 | 5
5 | 2016-06-30 | 2 | Ben Smith | {9,1,5,6} | 5.5 | 5.5
6 | 2016-06-30 | 2 | Tom Brown | {} | None | None
7 | 2016-06-29 | 4 | Tom Brown | {2} | 2 | 2
8 | 2016-06-30 | 2 | Tom Brown | {2,4} | 3 | 3
9 | 2016-06-30 | 1 | Tom Brown | {2,4,2} | 2 | 2
Postgres 没有 MEDIAN
的 built-in 聚合函数。但是,您可以使用 Postgres wiki. This snippet is also part of the ulib_agg user-defined library.
创建后,您可以像 SUM
或 STRING_AGG
等具有类似 window
规范的任何聚合函数一样使用它。 Postgres 为您提供了为以逗号分隔的聚合函数指定多个 window
定义的选项。
因此,要获取前 20 条记录的 MEDIAN
,您的 window 可以定义为在此查询中。
SELECT
j.* , array_agg(position) over w as previous_positions,
median(position) over w_20 as med_20
FROM jockeys j
WINDOW w as
( partition by name ORDER BY id rows between
unbounded preceding and 1 preceding
),
w_20 as
( partition by name ORDER BY id rows between
20 preceding and 1 preceding
)
此外,如果您想截断小数位,您可以应用 ROUND
函数。