如何使用任何Oracle函数选择计数作为Oracle总数的百分比?

时间:2011-07-07 15:34:38

标签: sql oracle aggregate-functions

我有一个SQL语句,它计算结束日期为null的活动包的总行数。我目前正在使用(x/y) * 100

执行此操作
SELECT (SELECT COUNT(*) 
          FROM packages 
         WHERE end_dt IS NULL) / (SELECT COUNT(*) 
                                    FROM packages) * 100 
  FROM DUAL;

我想知道是否有办法利用任何Oracle函数来更轻松地表达这一点?

3 个答案:

答案 0 :(得分:9)

我没有意识到任何功能,但您可以简单地将查询设为:

SELECT SUM(CASE WHEN p.end_dt IS NULL THEN 1 ELSE 0 END) / COUNT(*) * 100
  FROM PACKAGES p

答案 1 :(得分:6)

所以,基本上公式是

COUNT(NULL-valued "end_dt") / COUNT(*) * 100

现在,COUNT(NULL-valued "end_dt")在语法上是错误的,但它可以表示为COUNT(*) - COUNT(end_dt)。所以,公式可以是这样的:

(COUNT(*) - COUNT(end_dt)) / COUNT(*) * 100

如果我们稍微简化它,我们会得到这个:

SELECT (1 - COUNT(end_dt) * 1.0 / COUNT(*)) * 100 AS Percent
FROM packages

* 1.0位将COUNT的整数结果转换为非整数值,因此也使除法成为非整数。

上面的句子和脚本的相应部分原来是完全垃圾。与其他一些数据库服务器不同,即使两个操作数都是整数,Oracle也不会执行整数除法。 This doc page不包含除法运算符的这种行为的提示。

答案 2 :(得分:3)

原始帖子在牙齿上有点长,但这应该有效,使用自Oracle 8i以来可用的“ ratio_to_report ”功能:

SELECT
  NVL2(END_DT, 'NOT NULL', 'NULL') END_DT,
  RATIO_TO_REPORT(COUNT(*)) OVER () AS PCT_TOTAL
FROM
  PACKAGES
GROUP BY
  NVL2(END_DT, 'NOT NULL', 'NULL');