SQL创建一个列,其中包含类别的平均值和一些过滤器

问题描述 投票:0回答:2

我的目标是在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。另外,一些方法的原始计算是错误的,所以我也更新了。

sql
2个回答
0
投票

您可以使用相关子查询。这是一个例子:

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()来获取“邻居”的数量。


0
投票

我试图将答案留给非常通用的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
© www.soinside.com 2019 - 2024. All rights reserved.