我是 SQL 的新手,我确信这一定是一个常见问题,但我找不到解决方案。因此,如果您至少能为我指出正确的方向,那就太好了。
我有一个名为 forecasts 的表,其中包含产品的所有预测列表,其中 products 是一个单独的表,其中包含所有唯一产品的列表,其中数字作为标识符。
我正在尝试根据预测表计算所有产品的平均预测
预测表
CREATE TABLE forecasts
(
id INTEGER PRIMARY KEY NOT NULL,
month DATE,
quantity INTEGER,
extract_date DATE,
product_number VARCHAR,
final BOOLEAN DEFAULT false
);
我目前正在使用以下查询并迭代 ruby on rails 中的每个项目以生成平均预测
单品平均查询
WITH three_month_forecast AS (
SELECT product_number, month, sum(quantity) as forecast
FROM forecasts
WHERE extract_date >= '2016-08-01'::DATE - INTERVAL '1 month'
AND extract_date < '2016-08-01'::DATE
AND final = TRUE
AND month >= '2016-08-01'::DATE
AND month < '2016-08-01'::DATE + INTERVAL '3 months'
AND product_number = '100046119'
GROUP BY product_number, month, extract_date
ORDER BY month
)
SELECT avg(forecast) FROM three_month_forecast
产品数据库中大约有 10 万个项目,因此需要一段时间才能在 Rails 中完成。它在 SQL 中应该快得多,而不必单独遍历每个项目。
知道如何对产品数据库中的所有项目运行平均查询,以便它返回一个看起来像这样的表
产品编号 |平均预测
感谢任何帮助。谢谢
编辑
包含一个产品的示例计算的 sqlfiddle http://sqlfiddle.com/#!15/ab1637/2
编辑2
添加查询说明。该表目前没有任何索引
Aggregate (cost=15074.16..15074.17 rows=1 width=8) (actual time=432.189..432.190 rows=1 loops=1)
CTE three_month_forecast
-> Sort (cost=15074.13..15074.14 rows=1 width=22) (actual time=431.935..431.935 rows=3 loops=1)
Sort Key: forecasts.month
Sort Method: quicksort Memory: 25kB
-> HashAggregate (cost=15074.11..15074.12 rows=1 width=22) (actual time=431.354..431.363 rows=3 loops=1)
-> Seq Scan on forecasts (cost=0.00..15074.08 rows=3 width=22) (actual time=0.765..431.255 rows=3 loops=1)
Filter: (final AND (extract_date >= '2016-07-01 00:00:00'::timestamp without time zone) AND (extract_date < '2016-08-01'::date) AND (month >= '2016-08-01'::date) AND (month < '2016-11-01 00:00:00'::timestamp without time zone) AND ((product_number)::text = '100046119'::text))
Rows Removed by Filter: 442623
-> CTE Scan on three_month_forecast (cost=0.00..0.02 rows=1 width=8) (actual time=431.959..431.962 rows=3 loops=1)
Total runtime: 432.513 ms
最终编辑
@QuoVadis 解决方案非常有效。当我查看解决方案时,它是如此明显。谢谢。
最佳答案
这应该可以做到。
WITH three_month_forecast AS (
SELECT product_number, month, sum(quantity) as forecast
FROM forecasts
WHERE extract_date >= '2016-08-01'::DATE - INTERVAL '1 month'
AND extract_date < '2016-08-01'::DATE
AND final = TRUE
AND month >= '2016-08-01'::DATE
AND month < '2016-08-01'::DATE + INTERVAL '3 months'
AND product_number in (select distinct product_number from forecasts)
GROUP BY product_number, month, extract_date
ORDER BY month
)
SELECT avg(forecast), product_number FROM three_month_forecast
group by product_number
参见示例 here
关于sql - 针对postgresql中表中每一行的计算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39137488/