[英]Postgres SQL calculate average of calculated totals
I'm trying to write a query to return all products with higher than average dollar sales. 我正在尝试编写一个查询来返回所有高于平均美元销售额的产品。 The relevant tables and columns are:
相关的表格和列是:
I can write the subquery that gets dollar sales for each product, but I'm having trouble applying the average function to that subquery. 我可以编写每个产品获得美元销售额的子查询,但是我在将该平均函数应用于该子查询时遇到了麻烦。 Everything I try returns a syntax error.
我尝试的一切都会返回语法错误。 Following is what I thought should be close to the answer:
以下是我认为应该接近答案:
select avg(sum) as avg_sales
from (
select sum(b.quantity * a.price) as total_sales
from products a, orderlines b
where a.prod_id = b.prod_id
group by a.prod_id
);
When I try this, I get: 当我尝试这个时,我得到:
ERROR: subquery in FROM must have an alias.
错误:FROM中的子查询必须具有别名。
I don't get this, but I'm new to Postgres. 我不明白,但我是Postgres的新手。 Anyway, adding an alias gives me:
无论如何,添加别名给了我:
select avg(totals) as avg_sales
from (
select sum(b.quantity * a.price) as total_sales
from products a, orderlines b
where a.prod_id = b.prod_id group by a.prod_id
) as totals;
When I try this, I get: ERROR: function avg(record) does not exist 当我尝试这个时,我得到:错误:函数avg(记录)不存在
I realize the above code is just getting the overall average sales. 我意识到上面的代码只是获得了整体平均销售额。 If I can get average sales, then it should be easy to get the products that are above average.
如果我能获得平均销售额,那么应该很容易获得高于平均水平的产品。
When I try this, I get: ERROR: function avg(record) does not exist
当我尝试这个时,我得到:错误:函数avg(记录)不存在
This is because you are passing the alias of the derived table to the avg()
function, which means you are passing a complete row (=record) to it, not a single column (value). 这是因为您将派生表的别名传递给
avg()
函数,这意味着您将完整的行(=记录)传递给它,而不是单个列(值)。
To get that working you need to use: 要使其正常工作,您需要使用:
select avg(totals.total_sales) as avg_sales
from (
select sum(ol.quantity * p.price) as total_sales
from products p
join orderlines ol on p.prod_id = ol.prod_id
group by p.prod_id
) as totals;
Note that I replaced the ancient, outdated and fragile implicit join with a modern explicit JOIN
operator. 请注意,我用现代显式
JOIN
运算符替换了古老的,过时的和脆弱的隐式连接。 If you are learning SQL you should get used to that syntax. 如果你正在学习SQL,你应该习惯这种语法。
To get the products with a higher then average sale, you need to calculate both: the sales per product and the average sale. 要获得高于平均销售额的产品,您需要同时计算:每种产品的销售额和平均销售额。
This can be achieved by using a window function while aggregating: 这可以通过在聚合时使用窗口函数来实现:
select p.prod_id,
sum(ol.quantity * p.price) as total_sales,
avg(sum(ol.quantity * p.price)) over () as average_sales
from products p
join orderlines ol on p.prod_id = ol.prod_id
group by p.prod_id;
This can now be wrapped in a derived table to filter out those with a lower total sales: 现在可以将其包装在派生表中,以过滤掉总销售额较低的表:
select *
from (
select p.prod_id,
sum(ol.quantity * p.price) as total_sales,
avg(sum(ol.quantity * p.price)) over () as average_sales
from products p
join orderlines ol on p.prod_id = ol.prod_id
group by p.prod_id
) t
where total_sales >= average_sales;
SQLFiddle example: http://sqlfiddle.com/#!15/7f8ab/1 SQLFiddle示例: http ://sqlfiddle.com/#!15/7f8ab/1
You can try something like this. 你可以尝试这样的事情。 First using a sub query find the average sales, then get all the products above that sales
首先使用子查询查找平均销售额,然后获得高于该销售额的所有产品
SELECT p.prod_id, o.quantity
FROM products p INNER JOIN orderlines o
ON p.prod_id = o.prod_id
WHERE o.quantity > ( SELECT AVG(ol.quantity)
FROM products pr INNER JOIN orderlines ol
ON pr.prod_id = ol.prod_id
)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.