简体   繁体   English

如何从SQL oracle中的平均值中排除某些值

[英]How do I exclude certain values from an average in SQL oracle

If I have this table: Item(ItemID, descr, onhand, price) 如果我有此表: Item(ItemID, descr, onhand, price)

I am looking for prices that fall below the average of all the others. 我正在寻找价格低于其他所有产品的平均价格的产品。 So let's say I have item 1 , then I would be comparing it to the average of items 2-5 rather than the average of items 1-5 . 假设我有item 1 ,那么我将其与项目2-5的平均值而不是项目1-5的平均值进行比较。 I know it will be a correlated subquery, but I can't figure out this bit about the average. 我知道这将是一个相关的子查询,但是我无法弄清楚平均值。 So how do I exclude a non-specific item from the average? 那么,如何从平均值中排除非特定项目?

EDIT : as proved by @1010's transforms we can just compare items price to total average. 编辑 :通过@ 1010的变换证明,我们只能将商品价格与总平均值进行比较。

Smart solution: 智能解决方案:

( provides same results as straightforward, but executes much faster on large data ) 提供与直接操作相同的结果,但是在大数据上执行得更快

SELECT 
    t.ItemId,
    t.descr,
    t.onhand,
    t.price
from Item t
JOIN (
SELECT AVG(price) AS price
FROM Item 
) item_avg ON t.price < item_avg.price

Straightforward solution: 简单的解决方案:

This does the trick, however, at the moment I can't see ways to optimize it (it's an "execution plan killer") 这可以解决问题,但是,目前我还看不到优化它的方法(这是“执行计划的杀手”)

SELECT 
    t.ItemId,
    t.descr,
    t.onhand,
    t.price
from Item t
WHERE t.price < (
  SELECT AVG(T2.price) 
  FROM Item t2 
  WHERE t2.ItemId <> t.ItemID
)

For a table with such values: 对于具有此类值的表:

ItemId  descr   onhand  price   CalculatedAverage
1       desc1   1       23      40
2       desc2   1       5       44.5
3       desc3   1       100     20.75
4       desc4   1       35      37
5       desc5   1       20      40.75

It produces the following output 它产生以下输出

ItemId  descr   onhand  price
1       desc1   1       23
2       desc2   1       5
4       desc4   1       35
5       desc5   1       20

let's say item i has price p_i, then you want to check 假设我的商品价格为p_i,那么您要检查

p_i < (p_1 + ... + p_i-1 + p_i+1 + ... + p_n)/(n-1)

but it's equivalent to 但这相当于

      p_i * (n-1) < (p_1 + ... + p_n) - p_i

p_i * (n-1) + p_i < (p_1 + ... + p_n)

  p_i * (n-1 + 1) < (p_1 + ... + p_n)

    (p_i * n) / n < (p_1 + ... + p_n) / n

              p_i < AVG(p)

so just compare each price with the average of all prices. 因此,只需将每个价格与所有价格的平均值进行比较即可。 it's the same. 一样的。

EDIT 编辑

following Kirill's suggestion here's another query to get the prices below the average 按照基里尔的建议,这是另一个使价格低于平均价格的查询

SELECT ItemID, descr, onhand, price
  FROM Item
 WHERE price < (SELECT AVG(price) FROM Item)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM