我的目标是在mysql表中创建两列(让我们称之为NEW COL1和NEW COL2)
首先,在NEW_COL1中,我希望得到属于同一类别(BRAND)的所有观察值的某个变量(在我的例子中为价格)的平均值,并且关于另一个变量(KM)的距离接近。
示例:对于第一次观察(一辆6万公里的奥迪),我希望在它旁边有一个列,所有奥迪的平均价格要多20 000公里或者减少20 000公里
其次,我不知道如何做一个简单的操作,用%计算类别的频率(没有复杂的连接)
我想要实现的目标(Original Image):
+ -- + ------- + ------ + ----- + -------- + ----------- + _------- + -------------- +
| ID | Brand | KM | Price | NEW_COL1 | | NEW_COL2 | |
+ -- + ------- + ------ + ----- + -------- + ----------- + _------- + -------------- +
| 1 | audi | 60000 | 15000 | 14000 | MEAN(1,2) | 45% | #audi/total |
| 2 | audi | 80000 | 13000 | 13333.33 | MEAN(2,3,4) | 45% | |
| 3 | audi | 90000 | 12000 | 12500 | MEAN(2,3) | 45% | |
| 4 | audi | 120000 | 15000 | 7500 | MEAN(4,5) | 45% | |
| 5 | audi | 130000 | 15000 | 7500 | MEAN(4,5) | 45% | |
| 6 | Porsche | 60000 | 30000 | 28000 | MEAN(6,7) | 45% | #porsche/total |
| 7 | Porsche | 80000 | 26000 | 26666.67 | MEAN(6,7,8) | 45% | |
| 8 | Porsche | 90000 | 24000 | 25000 | MEAN(7,8) | 45% | |
| 9 | Porsche | 120000 | 16000 | 15000 | MEAN(9,10) | 45% | |
| 10 | Porsche | 130000 | 14000 | 15000 | MEAN(9,10) | 45% | |
| 11 | Porsche | 170000 | 8000 | 8000 | MEAN(11) | 45% | |
+ -- + ------- + ------ + ----- + -------- + ----------- + _------- + -------------- +
你有什么主意吗?
编者注:根据NEW_COL1之后的列中的描述和数据的排序,我将ID为4,5,9,10的KM更改为120,000和130,000。另外,一些方法的原始计算是错误的,所以我也更新了。
您可以使用相关子查询。这是一个例子:
select c.*,
(select avg(c2.price)
from cars c2
where c2.brand = c.brand and
c2.km between c.km - 20000 and c.km + 20000
) as avg_price
from cars c;
您可以使用count(*)
而不是avg()
来获取“邻居”的数量。
我试图将答案留给非常通用的sql,因为你没有提供RDBMS。加入对您来说可能会快一点。要获得NEW_COL1,请尝试此操作
select a.*, AVG(cast(b.Price as float)) as NEW_COL1
from Cars a
left join Cars b
on b.Brand = a.Brand
and b.KM between a.KM - 20000 and a.KM + 20000
group by a.ID, a.Brand, a.KM, a.Price
就个人而言,我喜欢使用cross申请这种类型的查询,但不是每个版本的sql都支持(我在看你,MySQL)。
获取NEW_COL2有点棘手,但这样的事情应该可以解决问题:
select a.*, AVG(cast(b.Price as float)) as NEW_COL1
, cast(cast(( select COUNT(*)
from Cars x
where x.Brand = a.Brand
group by Brand
) as float) / ( select COUNT(*) from Cars) * 100 as int) as NEW_COL2
from Cars a
left join Cars b
on b.Brand = a.Brand
and b.KM between a.KM - 20000 and a.KM + 20000
group by a.ID, a.Brand, a.KM, a.Price