If I have this table: 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
. 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.
( 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
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_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)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.