[英]SQL-ex.ru #26 Selecing average from two tables
I had a question about a sql query on the website http://www.sql-ex.ru/ .我有一个关于网站http://www.sql-ex.ru/上的 sql 查询的问题。 The query asks for :
查询要求:
Define the average price of the PCs and laptops produced by maker A.
定义制造商 A 生产的个人电脑和笔记本电脑的平均价格。
The database schema is as follows:数据库架构如下:
Product(maker, model, type)
PC(code, model, speed, ram, hd, cd, price)
Laptop(code, model, speed, ram, hd, screen, price)
Printer(code, model, color, type, price)
I wrote my query as:我将查询写为:
SELECT AVG(t.k) AS Avg_Price
FROM
(SELECT AVG(A.price) AS k
FROM PC A
JOIN Product B ON(A.model=B.model)
WHERE B.maker='A'
UNION ALL
SELECT AVG(C.price) AS k
FROM Laptop C
JOIN PRODUCT D ON(C.model=D.model)
WHERE D.maker='A') AS t
The problem is that it does not return the correct answer.问题是它没有返回正确的答案。 The average returned is much higher than expected.
平均回报远高于预期。 Is the way the average is calculated wrong?
计算平均值的方式是错误的吗? How do I change the query so that it returns the expected answer?
如何更改查询以使其返回预期的答案? Any help would be appreciated.
任何帮助,将不胜感激。
Thanks谢谢
You're averaging pc prices and laptop prices separately, then averaging the averages together.您将分别计算个人电脑价格和笔记本电脑价格的平均值,然后将平均值放在一起。 Your query was good except that you shouldn't have averaged the prices in the sub queries.
您的查询很好,只是您不应该对子查询中的价格进行平均。 simply return the prices in the sub queries and average at the top level:
只需返回子查询中的价格和顶级的平均值:
select
AVG( Price ) Avg_Price
from
(
(
select
pc.Price
from
PC pc
join Produt prod
on pc.Model = prod.Model
where
prod.Maker = 'A'
)
union all
(
select
pc.Price
from
Laptop l
join Produt prod
on l.Model = prod.Model
where
prod.Maker = 'A'
)
) q
SELECT AVG(datatable.price) FROM
(
(SELECT PC.Price FROM PC INNER JOIN Product p1 ON PC.model=P1.model
WHERE P1.maker='A')
UNION ALL
(SELECT Laptop.price FROM Laptop INNER JOIN Product p2 ON
Laptop.model=P2.model WHERE P2.maker='A')
) datatable
Right.对。
The result of Your query:您的查询结果:
Avg_Price
平均价格
754.1666
754.1666
Your query is wrong.您的查询是错误的。 It is typically like how you to aggregation on distributed system.
这通常就像您如何在分布式系统上进行聚合一样。 You can do aggregation on distributed node, then bring back the aggregation data and do agg on top of you return data, only except for the aggregation is transferable.
您可以在分布式节点上进行聚合,然后将聚合数据带回来并在返回数据之上进行聚合,除非聚合是可转移的。 AVG is not transerable.
AVG不可转换。 (1+2+3+4+5)/5 <> ((1+2)/2 + (1+2+3)/3)
(1+2+3+4+5)/5 <> ((1+2)/2 + (1+2+3)/3)
with t1 as
(SELECT price, type from pc left join product on product.model = pc.model where maker = 'A'
UNION ALL
SELECT price, type from laptop left join product on product.model = laptop.model where maker = 'A')
select avg(price) from t1
It also work它也工作
SELECT Avg(price) AS avg_price
FROM (SELECT pc.price
FROM pc
INNER JOIN product
ON pc.model = product.model
WHERE maker = 'A'
UNION ALL
SELECT laptop.price
FROM laptop
INNER JOIN product
ON laptop.model = product.model
WHERE maker = 'A') Any_name
SELECT AVG(resultList.Price)
FROM
(
SELECT a.Price
FROM PC a INNER JOIN Product B
on a.Model = B.Model
WHERE B.Maker = 'A'
UNION ALL
SELECT c.Price
FROM Laptop c INNER JOIN Product d
on c.Model = d.Model
WHERE d.Maker = 'A'
) resultList
select AVG(P.price) as avg_price
from
(
select price, model from PC
UNION ALL
select price, model from Laptop
) P
join Product ON P.model = Product.model
where maker = 'A'
SELECT AVG(price) FROM
(
SELECT PC.price, Product.maker FROM PC JOIN Product ON(PC.model=Product.model)
UNION ALL
SELECT Laptop.price, Product.maker FROM Laptop JOIN Product ON (Laptop.model = Product.model)
) T
GROUP BY T.maker HAVING T.maker = 'A'
It works because at first you select all laptop and pc prices, next you choose only records where maker = 'A', and the last step is counting an avg price.之所以有效,是因为首先您选择了所有笔记本电脑和个人电脑的价格,接下来您只选择了 maker = 'A' 的记录,最后一步是计算平均价格。
Select avg(price) from
((select price,model from pc
union all
select price,model from laptop) a inner join product on product.model=a.model and product.maker='A' )
Firstly, I think that it would be better if I union
price
and model
of both tables and afterwards we can find average(price)
from maker A.首先,我认为它会更好,如果我
union
price
和model
两个表,之后我们可以发现average(price)
从制造商A.
I always have great struggle with JOINS(personally), so try this solution without joins.我总是对 JOINS(个人)有很大的挣扎,所以试试这个没有连接的解决方案。 using IN Operator
使用 IN 运算符
with cte as (
SELECT price, model, code
FROM pc
WHERE model
IN (SELECT model FROM product WHERE maker = 'A')
UNION
SELECT price, model, code
FROM laptop
WHERE model
IN (SELECT model FROM product WHERE maker = 'A')
)
SELECT AVG(price) FROM cte
select avg(price) as avg_price from
(select price
from Product, PC
where Product.model = PC.model
and maker = 'A'
union all
select price
from Product, Laptop
where Product.model = Laptop.model
and maker='A') avg_price
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.