MySQL和平均计算给出不同的结果

时间:2017-10-13 12:13:40

标签: mysql

我创建了一个名为test的测试表,其中包含一些如下所示的示例数据:

enter image description here

如果我将每个用户的值相加并除以该user_id的条目总数并将其乘以100,我得到一个百分比。例如,

for user_id 1 there are a total of 6 records and the values add up to 4. So 4/6*100 = 66.67%

for user_id 2 there are a total of 8 records and the values add up to 6. So 6/8*100 = 75%

我可以使用以下SQL获取这些值:

SELECT a.user_id, a.total_present / (SELECT count(*) as total_sessions FROM test WHERE session_date BETWEEN '2017-10-01' AND '2017-10-15' AND user_id = a.user_id) * 100 AS attendance_percentage, a.total_present 
FROM (
   SELECT user_id, count(*) as total_present 
   FROM test t 
   WHERE t.session_date BETWEEN '2017-10-01' AND '2017-10-15' AND t.value=1 
   GROUP BY user_id
) a ORDER BY a.user_id ASC

如果我将百分比加上并除以用户数,那么平均得分为70.83%

我想简化这个只是简单地总结所有记录并除以记录总数并乘以100这样:

SELECT ((SELECT count(*) as total_present FROM test t WHERE t.session_date BETWEEN '2017-10-01' AND '2017-10-15' AND t.value=1) / (SELECT count(*) as total_sessions FROM test WHERE session_date BETWEEN '2017-10-01' AND '2017-10-15')) * 100 AS average_percentage

然而,这并没有给我相同的平均计算,因为每个用户具有不同的总会话数。如果两个用户具有相同数量的会话,则匹配。

所以问题是,有没有办法使用我的简化方法来计算这个,但是结果更准确到我得到每个用户百分比,然后将其加起来除以总用户?

2 个答案:

答案 0 :(得分:0)

您的查询很复杂。要获得用户的attendance_percentage,您可以简单地获取avg值(因为它已经是二进制)并将其乘以100.以下是对此的查询。

SELECT user_id, sum(value) as total_present, avg(value)*100 as attendance_percentage 
FROM test t 
WHERE t.session_date BETWEEN '2017-10-01' AND '2017-10-15'
GROUP BY user_id

最后计算平均出勤率 - 百分比,只需从上面的查询得到平均值。像这样。

select avg(attendance_percentage) from
(SELECT user_id, sum(value) as total_present, avg(value)*100 as attendance_percentage 
FROM test t 
WHERE t.session_date BETWEEN '2017-10-01' AND '2017-10-15'
GROUP BY user_id)q;

我还为您创建了此sqlfiddle,以便您可以测试查询。

编辑:如果您的值不是二进制,您可以使用原始查询来查找用户明智的attendance_percentage,并使用Avg()函数简单地获取它的平均值。因此,您的查询会更改为此。

select avg(attendance_percentage) from
(SELECT a.user_id, a.total_present / (SELECT count(*) as total_sessions FROM test WHERE session_date BETWEEN '2017-10-01' AND '2017-10-15' AND user_id = a.user_id) * 100 AS attendance_percentage, a.total_present 
FROM (
   SELECT user_id, count(*) as total_present 
   FROM test t 
   WHERE t.session_date BETWEEN '2017-10-01' AND '2017-10-15' AND t.value=1 
   GROUP BY user_id
) a ORDER BY a.user_id ASC)q.

以下是更新后的fiddle

答案 1 :(得分:0)

我建议您阻止使用子查询,这不是一个很好的理由。说实话,大多数情况下,如果没有它们以及子查询,你可以做到这一点通常会导致性能下降,而且根本无法扩展。

但是,我认为您的查询看起来像这样:

SELECT user_id, sum(IF(t.value=1,1,0)) as total_present, (total_present/count(*))*100 AS attendance_percentage
FROM test t 
WHERE t.session_date BETWEEN '2017-10-01' AND '2017-10-15'
GROUP BY user_id

我希望有帮助