这是我发布的previously这个精妙答案的变体:
我有一个数据库表,其中:
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
如何有效查询表,以便可以使用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);
我希望表格输出看起来像这样
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
答案 0 :(得分:0)
Postgres没有MEDIAN
的内置聚合函数。但是,您可以使用Postgres wiki中提供的功能代码段创建一个。此摘录也是ulib_agg user-defined library的一部分。
创建后,您可以像使用类似SUM
规范的STRING_AGG
或window
之类的聚合函数一样使用它。 Postgres为您提供了为逗号分隔的聚合函数指定多个window
定义的选项。
因此,要获得前20条记录的MEDIAN
,可以按照此查询的定义窗口。
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
函数。