问题 MySQL中的加权平均值计算?


我目前正在使用以下查询来获取一些数字:

SELECT gid, count(gid), (SELECT cou FROM size WHERE gid = infor.gid)       
FROM infor 
WHERE id==4325 
GROUP BY gid;

我目前阶段得到的输出如下:

+----------+-----------------+---------------------------------------------------------------+
| gid      | count(gid)      | (SELECT gid FROM size WHERE gid=infor.gid)                    |
+----------+-----------------+---------------------------------------------------------------+
|       19 |               1 |                                                            19 | 
|       27 |               4 |                                                            27 | 
|      556 |               1 |                                                           556 | 
+----------+-----------------+---------------------------------------------------------------+

我想计算加权平均值,即

(1 * 19 + 4 * 27 + 1 * 556)/(19 + 27 + 556)

有没有办法使用单个查询执行此操作?


3244
2017-10-08 01:17


起源



答案:


使用:

SELECT SUM(x.num * x.gid) / SUM(x.cou)
  FROM (SELECT i.gid,
               COUNT(i.gid) AS num,
               s.cou
          FROM infor i
     LEFT JOIN SIZE s ON s.gid = i.gid
         WHERE i.id = 4325
      GROUP BY i.gid) x

14
2017-10-08 01:58



太棒了......非常感谢你。我准备在一个过程中编写一个嵌套循环,但后来发现一篇文章说“如果你需要一个嵌套循环,那么你没有看到一个JOIN”:) - Legend
@legend:建议是正确的,但如果有多个子节点与父节点关联,JOIN也会冒充气记录的风险。如果您想要父级的不同行,最好使用子查询(EXISTS将是我的推荐)。 - OMG Ponies
我懂了。在我的情况下,只有一个元素,但我会记住你的建议。 - Legend
@Legend:非常好 - 您对数据的了解越多,您的查询就越好。 - OMG Ponies


答案:


使用:

SELECT SUM(x.num * x.gid) / SUM(x.cou)
  FROM (SELECT i.gid,
               COUNT(i.gid) AS num,
               s.cou
          FROM infor i
     LEFT JOIN SIZE s ON s.gid = i.gid
         WHERE i.id = 4325
      GROUP BY i.gid) x

14
2017-10-08 01:58



太棒了......非常感谢你。我准备在一个过程中编写一个嵌套循环,但后来发现一篇文章说“如果你需要一个嵌套循环,那么你没有看到一个JOIN”:) - Legend
@legend:建议是正确的,但如果有多个子节点与父节点关联,JOIN也会冒充气记录的风险。如果您想要父级的不同行,最好使用子查询(EXISTS将是我的推荐)。 - OMG Ponies
我懂了。在我的情况下,只有一个元素,但我会记住你的建议。 - Legend
@Legend:非常好 - 您对数据的了解越多,您的查询就越好。 - OMG Ponies


您可以将原始查询作为子查询放置并SUM记录。我无法测试这个,因为我没有你做的数据集,但它应该在理论上工作;)

SELECT SUM(gid)/SUM(weights) AS calculated_average FROM (
  SELECT gid, (COUNT(gid) * gid) AS weights
  FROM infor 
  WHERE id = 4325 
  GROUP BY gid);

1
2017-10-08 01:58



这种方法的+1。谢谢。只是好奇知道哪一个更有效率。将跑到 EXPLAIN 并看到。 - Legend
@Legend,没问题。你可能实际上需要 JOIN但是从OP来看,我没有看到它的必要性。 - Jason McCreary