这是后续this https://stackoverflow.com/questions/48000013/optimize-slow-aggregates-in-lateral-join问题,我的查询被改进为使用窗口函数而不是内部的聚合LATERAL
加入。虽然现在查询速度快得多,但我发现结果不正确。
我需要对 x 年跟踪时间范围执行计算。例如,price_to_maximum_earnings
通过获取每行计算max(earnings)
十多年前到当前行,并除以price
通过结果。为简单起见,我们在这里使用 1 年。
SQL小提琴 http://sqlfiddle.com/#!17/648ff/11对于这个问题。 (Postgres 9.6)
举个简单的例子,price
and peak_earnings
for 2010-01-01
可以像这样单独计算:
SELECT price
FROM security_data
WHERE date = '2010-01-01'
AND security_id = 'SPX';
SELECT max(earnings) AS min_earnings
FROM bloomberg.security_data
WHERE date >= '2000-01-01'
AND date <= '2010-01-01'
AND security_id = 'SPX';
去做这个per row,我使用以下内容:
SELECT security_id, date, price
, CASE WHEN date1 >= min_date
THEN price / NULLIF(max(earnings) FILTER (WHERE date >= date1) OVER w, 0) END AS price_to_peak_earnings
FROM
(
SELECT record_id, security_id, price, date, earnings
, (date - interval '1 y')::date AS date1
, min(date) OVER (PARTITION BY security_id) AS min_date
FROM security_data
) d
WINDOW w AS (PARTITION BY security_id);
我相信这里的问题源于使用FILTER
,因为它似乎没有按照我想要的方式工作。请注意,在链接的 SQL Fiddle 中,我显示了以下结果FILTER
,并且对于每一行peak_earnings
and minimum_earnings
只是整个数据集的最大值和最小值。他们should是最大/最小值earnings
从 1 年前到当前行。
这里发生了什么?我从答案中知道this https://stackoverflow.com/questions/31396434/referencing-current-row-in-filter-clause-of-window-function我不能简单地说出的问题FILTER (WHERE date >= date1 AND date <= current_row.date)
,那么我缺少什么解决方案吗?我不能使用窗框,因为在任何给定的时间范围内我的行数都不确定,所以我不能只是说OVER (ROWS BETWEEN 365 PRECEDING AND CURRENT ROW)
。我可以使用框架吗and过滤器?这可能是一年多以前,然后过滤器可以捕获每个无效日期。我已经尝试过这个但没有成功。