【问题标题】:MySQL Average of some rows with special weightsMySQL 某些具有特殊权重的行的平均值
【发布时间】:2016-06-19 21:41:34
【问题描述】:

我有下表:

+----+----------+----------+----------+
| id |  Column1 |  Column2 |  Column3 |
+----+----------+----------+----------+
| 1  |  1       |  2014    |  0.2     | 
| 2  |  1       |  2013    |  0.5     | 
| 3  |  2       |  2014    |  1.9     | 
| 4  |  2       |  2013    |  1.4     | 
| 5  |  2       |  2012    |  1       | 
| 6  |  2       |  2011    |  0.4     | 
| 7  |  3       |  2016    |  1.4     | 
| 8  |  3       |  2015    |  1.2     | 
| 9  |  3       |  2014    |  0.7     | 
| 10 |  4       |  2015    |  0.5     | 
+----+----------+----------+----------+

我需要的是以下内容 我想对具有相同 Column1 值的行进行平均,但最新数据应乘以 0.6,其余数据乘以 0.3

例如
其中Column1 = 1, it should output the value of 0.2*0.6+0.5*0.3 Column1 = 2, 1.9*0.6+((1.4+1+0.4)/3)*0.3 Column1 = 3, 1.4*0.6+((1.2+0.7)/2)*0.3 Column1 = 4, 0.5

编辑:如果这对于一个查询来说太复杂了,我也很乐意做更多的事情。

【问题讨论】:

  • jpql有row_number或者其他窗口函数吗?
  • 表格有行号。但我不确定窗口功能。
  • 你知道 0.6 + 0.3 不等于 1 吗?因此,如果有 (11,5,2015,0.5) 和 (12,5,2014,0.5) 行,第 5 项的加权平均值将为 0.45 而不是 0.5

标签: mysql sql jpql


【解决方案1】:

在这里查看:sqlFiddle

SELECT 
    c1, 
    avg(c3), -- this here is the average per weight
    weight,  -- this is the weight
    avg(c3)*weight as weighted_avg -- product between the two
FROM
(
    SELECT
        table1.*,
        if(no_of_lines is null, 
           0.3,                   -- the default weight for >1 lines
           if(no_of_lines = 1 , 
              1,                  -- the weight if there's only 1 line
              0.6                 -- the weight for the 1st line if there are more
           )
        ) as weight
    FROM
        table1
    Left join
    (
        select min(id) as id, count(id) as no_of_lines ,c1
        from table1
        group by c1
    ) tmp on tmp.id = table1.id
) final
group by c1, weight
order by c1 ASC, weight DESC

会输出这个:

c1 | avg(c3) | weight | weighted_avg
------------------------------------
1  | 0.2     |    0.6 | 0.12
1  | 0.5     |    0.3 | 0.15
2  | 1.9     |    0.6 | 1.14
2  | 0.9333  |    0.3 | 0.279
3  | 1.4     |    0.6 | 0.84
3  | 0.95    |    0.3 | 0.285
4  | 0.5     |      1 | 0.5

你现在需要做的就是:

SELECT c1, sum(weighted_avg) FROM `that_select`
GROUP by c1

免责声明:
1)这可能可以简化一点,但这是另一个故事
2) 移除 cmets - 可能会给您带来错误

【讨论】:

  • 查看早期版本的 sqlFiddle。最后一个是/15。见sqlfiddle.com/#!9/eeb9f3/10这个版本没有预先计算每个重量的平均值。
猜你喜欢
  • 2018-04-28
  • 2010-10-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-30
  • 2016-03-20
  • 1970-01-01
相关资源
最近更新 更多