我有一张这样的表:
------------------
sl no | Error type
------------------
1 | err1
------------------
2 | err2
------------------
3 | err1
------------------
4 | err2
------------------
5 | err2
------------------
6 | err3
------------------
我想要的结果:
---------------------------
Error type | Count | %
---------------------------
err1 | 2 | 33.33
---------------------------
err2 | 3 | 50
---------------------------
err3 | 1 | 16.66
---------------------------
我正在使用以下查询来获得上述结果:
select
error as Error,
count(*) as Count,
100* count(*)/(select count(*) from logs) as Percentage
from logs
group by error;
它是否针对任务进行了优化?如果没有,我可以通过哪些其他有效方式获取这些信息?
答案 0 :(得分:2)
此查询将每行执行count(*)
。我查询一次,然后将其加入个人计数:
SELECT a.error, a.cnt, 100 * a.cnt / b.total_count AS percentage
FROM (SELECT error, COUNT(*) as cnt
FROM logs
GROUP BY error) a
CROSS JOIN (SELECT COUNT(*) AS total_count FROM logs) b
答案 1 :(得分:0)
不确定您使用的DBMS。如果您的DBMS允许您使用聚合函数作为窗口函数(您可以在Oracle中执行此操作),那么您可以执行以下操作:
SELECT error, COUNT(*) AS count, 100*COUNT(*)/COUNT(*) OVER ( ) AS percentage
FROM logs
GROUP BY error
(注意,OVER()子句为空,表示总计数是想要的。)
希望这有帮助。
答案 2 :(得分:0)
在您尝试优化任何查询之前,您应该查看执行计划。例如,在MSSQL中,查询计划将如下所示:
您可以非常清楚地看到两个索引扫描("嵌套循环"右侧的顶部和底部分支)。顶部分支正在执行count(*)
聚合以获取表中的总行数。这样做一次,包含计数的结果单行与底部分支中的每一行配对。底部分支正在为每个组执行count
聚合。
因此,如果不更改高度可读的查询,您可能已经有了一个有效的执行计划。