我尝试计算2个表中的项目百分比。
表:
operation_systems
id | title
1001 | Windows
1002 | Apple
1003 | Linux
sub_pref
sub_id | id | user_id
1 | 1001 | 1
2 | 1001 | 2
3 | 1003 | 1
4 | 1003 | 2
5 | 1003 | 1
6 | 1003 | 2
7 | 1003 | 3
8 | 1003 | 4
9 | 1003 | 5
10 | 1002 | 5
使用以下查询:
SELECT operation_systems.id, operation_systems.title,
COUNT(sub_pref.id) AS count, ROUND( SUM( 100 ) / total ) AS percentage
FROM operation_systems
CROSS JOIN (SELECT COUNT( * ) AS total FROM operation_systems)x
LEFT JOIN sub_pref ON sub_pref.id = operation_systems.id
GROUP BY operation_systems.id
ORDER BY count DESC;
目前的结果:
Apple | 1 | 33%
Windows | 2 | 33%
Linux | 7 | 33%
期望的结果:
Apple | 1 | 10%
Windows | 2 | 20%
Linux | 7 | 70%
如何获得正确的百分比?
答案 0 :(得分:1)
错误在于这部分代码:
SELECT COUNT( * ) AS total FROM operation_systems
这将为您提供operation_systems的总数,即3,而不是sub_pref中引用每个operation_system的总行数。结果你得到33%的百分比,因为你只是将100除以3,三次。
如果您改变思考方式,这个问题就更容易解决了。您当前正在从operation_systems中进行选择,然后从sub_pref将数据提取到您的查询中。但是,您真正想要做的是在sub_pref中聚合数据,然后从operation_systems为每个结果提供一个友好名称。
我建议:
SELECT operation_systems.title,
COUNT(sub_pref.id) AS COUNT,
ROUND(COUNT(sub_pref.id) * 100 /
(SELECT COUNT(*)
FROM sub_pref)) AS percentage
FROM sub_pref
LEFT JOIN operation_systems ON operation_systems.id = sub_pref.id
GROUP BY sub_pref.id
ORDER BY COUNT DESC
我创建了an sqlfiddle,其中包含您提供的架构/数据以及上述解决方案。只需点击"运行SQL"看它是否有效。
答案 1 :(得分:0)
试试这个:
SELECT os.id, os.title, sp.num_sp, os_total.total, ((sp.num_sp / os_total.total) * 100)
FROM operation_systems os
JOIN (
SELECT id as os_id, COUNT(*) as num_sp
FROM sub_pref
GROUP BY id
) sp ON os.id = sp.os_id
CROSS JOIN (
SELECT COUNT(*) as total
FROM sub_pref
) os_total
答案 2 :(得分:0)
这是一个易于阅读的查询:
SELECT title, (COUNT(sub_pref.id) / t.total) * 100 AS percent
FROM operation_systems, sub_pref, (SELECT COUNT(*) AS total FROM sub_pref) t
WHERE operation_systems.id = sub_pref.id
GROUP BY sub_pref.id
ORDER BY percent
答案 3 :(得分:0)
实现它的另一种方式
select
os.id,
os.title,
ROUND( ( cnt / ( select count(*) from sub_pref )*100) ) as percentage
from operation_systems os
inner join (
select id,count(id) as cnt from sub_pref
group by id
)sp
on sp.id = os.id
group by os.id
order by os.title