如何在 BETWEEN 子句中插入 AVG?
How insert AVG in BETWEEN clause?
例如让我们以 Northwind 为例。我想使用 CASE 子句通过将 units_in_stock 与其 AVG 值进行比较来创建类别并将此值放在多个 BETWEEN 子句中。这就是我得到的:
SELECT product_name, unit_price, units_in_stock,
CASE
WHEN units_in_stock > (SELECT AVG(units_in_stock) + 10 FROM products) THEN 'many'
WHEN units_in_stock BETWEEN (SELECT AVG(units_in_stock) - 10 FROM products) AND (SELECT AVG(units_in_stock) + 10 FROM products) THEN 'average'
ELSE 'low'
END AS amount
FROM products
ORDER BY units_in_stock;
根据 pgAdmin 中的分析工具 AVG(units_in_stock) 计算了三次。有没有办法减少计算量?
您可以使用 window 函数代替子查询。另外,在第二个WHEN
条件中不需要使用BETWEEN
;大于平均值 + 10 的值由第一个分支处理,永远不会到达第二个分支。
我会这样表述:
SELECT product_name, unit_price, units_in_stock,
CASE
WHEN units_in_stock > AVG(units_in_stock) OVER() + 10 THEN 'many'
WHEN units_in_stock >= AVG(units_in_stock) OVER() - 10 THEN 'average'
ELSE 'low'
END AS amount
FROM products
ORDER BY units_in_stock;
我希望数据库优化查询,以便 window 平均值只计算一次。如果不是这种情况,另一种方法是先计算子查询中的平均值:
SELECT product_name, unit_price, units_in_stock,
CASE
WHEN units_in_stock > avg_units_in_stock + 10 THEN 'many'
WHEN units_in_stock >= avg_units_in_stock - 10 THEN 'average'
ELSE 'low'
END AS amount
FROM (SELECT p.*, AVG(units_in_stock) OVER() avg_units_in_stock FROM products p) p
ORDER BY units_in_stock;
例如让我们以 Northwind 为例。我想使用 CASE 子句通过将 units_in_stock 与其 AVG 值进行比较来创建类别并将此值放在多个 BETWEEN 子句中。这就是我得到的:
SELECT product_name, unit_price, units_in_stock,
CASE
WHEN units_in_stock > (SELECT AVG(units_in_stock) + 10 FROM products) THEN 'many'
WHEN units_in_stock BETWEEN (SELECT AVG(units_in_stock) - 10 FROM products) AND (SELECT AVG(units_in_stock) + 10 FROM products) THEN 'average'
ELSE 'low'
END AS amount
FROM products
ORDER BY units_in_stock;
根据 pgAdmin 中的分析工具 AVG(units_in_stock) 计算了三次。有没有办法减少计算量?
您可以使用 window 函数代替子查询。另外,在第二个WHEN
条件中不需要使用BETWEEN
;大于平均值 + 10 的值由第一个分支处理,永远不会到达第二个分支。
我会这样表述:
SELECT product_name, unit_price, units_in_stock,
CASE
WHEN units_in_stock > AVG(units_in_stock) OVER() + 10 THEN 'many'
WHEN units_in_stock >= AVG(units_in_stock) OVER() - 10 THEN 'average'
ELSE 'low'
END AS amount
FROM products
ORDER BY units_in_stock;
我希望数据库优化查询,以便 window 平均值只计算一次。如果不是这种情况,另一种方法是先计算子查询中的平均值:
SELECT product_name, unit_price, units_in_stock,
CASE
WHEN units_in_stock > avg_units_in_stock + 10 THEN 'many'
WHEN units_in_stock >= avg_units_in_stock - 10 THEN 'average'
ELSE 'low'
END AS amount
FROM (SELECT p.*, AVG(units_in_stock) OVER() avg_units_in_stock FROM products p) p
ORDER BY units_in_stock;