Oracle 甲骨文-案例依赖数学

Oracle 甲骨文-案例依赖数学,oracle,count,case,Oracle,Count,Case,我正在忙着做一些案件统计,希望有人能帮我。你知道怎么做吗 我要做的是对列执行一些数学运算,然后计算满足条件的记录数。例如,我有这些数据 REPORT bad_count good_count ------------------------------ Y 30 20 Y 1 100 我希望看到坏计数大于等于总计数20%的记录计数。。。(坏+好)像这样 REPORT stuff ------------- Y 1

我正在忙着做一些案件统计,希望有人能帮我。你知道怎么做吗

我要做的是对列执行一些数学运算,然后计算满足条件的记录数。例如,我有这些数据

REPORT  bad_count   good_count
------------------------------
Y       30          20
Y       1           100
我希望看到坏计数大于等于总计数20%的记录计数。。。(坏+好)像这样

REPORT  stuff
-------------
Y       1
这是我心中的疑问,但我收到了一个错误

select      REPORT,
            count(case round(bad_count / (good_count + bad_count) * 100) when >=20 then 1) as stuff
from        $A$
group by    REPORT

下面的建议答案有效

SELECT REPORT, COUNT(*) 
  FROM (SELECT REPORT, ROUND((bad_ct/(good_ct+bad_ct))*100) pct
         FROM $A$)
 WHERE pct >= 20
 GROUP BY REPORT;
但是,为什么这样重新编写时它不起作用呢

 SELECT         REPORT,
                count(case pct when >=20 then 1 end) as stuff
    FROM        (
                    SELECT  REPORT, 
                            ROUND((bad_ct/(good_ct+bad_ct))*100) pct
                    FROM    $A$
                )
    GROUP BY    REPORT

我之所以喜欢这样做,是因为我可能希望在有其他条件的情况下计算实例。例如,我还需要一个新的列“good_stuff”,这是一个计数,其中有多少记录具有非空的good_ct。

我相信您正在寻找

select      report,
            (case when round( total_bad/ (total_good + total_bad) * 100) >= 20
                  then 1
                  else 0
              end) stuff
from (
    select      REPORT,
                SUM(bad_count) total_bad,
                SUM(good_count) total_good
    from        $A$
    group by    REPORT
)

通过将聚合放在CASE语句中,您应该能够在没有子查询的情况下完成这项工作,但我觉得这个公式更容易理解。

我相信您正在寻找

select      report,
            (case when round( total_bad/ (total_good + total_bad) * 100) >= 20
                  then 1
                  else 0
              end) stuff
from (
    select      REPORT,
                SUM(bad_count) total_bad,
                SUM(good_count) total_good
    from        $A$
    group by    REPORT
)
通过将聚合放在CASE语句中,您应该能够在没有子查询的情况下完成这项工作,但我觉得这个公式更容易理解。

类似这样的内容:

SELECT REPORT, COUNT(*) 
  FROM (SELECT REPORT, ROUND((bad_ct/(good_ct+bad_ct))*100) pct
         FROM $A$)
 WHERE pct >= 20
 GROUP BY REPORT;
编辑:

我对这个问题的解释与其他回答者略有不同。我认为问题是“行的计数(按报告字段分组)是多少,其中行的错误计数>=行的总计数。”

测试给出:

SQL> CREATE TABLE TEST (REPORT VARCHAR2(10), bad_count INTEGER, good_count INTEGER);

Table created
SQL> INSERT INTO TEST VALUES('Y',30,20);

1 row inserted
SQL> INSERT INTO TEST VALUES('Y',1,100);

1 row inserted
SQL> INSERT INTO TEST VALUES('Y',20,80);

1 row inserted
SQL> INSERT INTO TEST VALUES('Y',19,80);

1 row inserted

SQL> commit;

Commit complete

SQL> 
SQL> SELECT REPORT, COUNT(*) FROM (
  2  SELECT REPORT, ROUND((bad_count/(good_count+bad_count))*100) pct
  3    FROM TEST)
  4   WHERE pct >= 20
  5   GROUP BY REPORT;

REPORT       COUNT(*)
---------- ----------
Y                   2

SQL> 
大概是这样的:

SELECT REPORT, COUNT(*) 
  FROM (SELECT REPORT, ROUND((bad_ct/(good_ct+bad_ct))*100) pct
         FROM $A$)
 WHERE pct >= 20
 GROUP BY REPORT;
编辑:

我对这个问题的解释与其他回答者略有不同。我认为问题是“行的计数(按报告字段分组)是多少,其中行的错误计数>=行的总计数。”

测试给出:

SQL> CREATE TABLE TEST (REPORT VARCHAR2(10), bad_count INTEGER, good_count INTEGER);

Table created
SQL> INSERT INTO TEST VALUES('Y',30,20);

1 row inserted
SQL> INSERT INTO TEST VALUES('Y',1,100);

1 row inserted
SQL> INSERT INTO TEST VALUES('Y',20,80);

1 row inserted
SQL> INSERT INTO TEST VALUES('Y',19,80);

1 row inserted

SQL> commit;

Commit complete

SQL> 
SQL> SELECT REPORT, COUNT(*) FROM (
  2  SELECT REPORT, ROUND((bad_count/(good_count+bad_count))*100) pct
  3    FROM TEST)
  4   WHERE pct >= 20
  5   GROUP BY REPORT;

REPORT       COUNT(*)
---------- ----------
Y                   2

SQL> 

利用Oracle的分析功能:

SELECT REPORT, 1 stuff
FROM (
   SELECT REPORT,
          sum(good_count) over (partition by REPORT) total_good,
          sum(bad_count) over (partition by REPORT) total_bad
   FROM REPORT 
) WHERE round( total_bad / (total_good + total_bad) * 100) >= 20
ORDER BY REPORT;

利用Oracle的分析功能:

SELECT REPORT, 1 stuff
FROM (
   SELECT REPORT,
          sum(good_count) over (partition by REPORT) total_good,
          sum(bad_count) over (partition by REPORT) total_bad
   FROM REPORT 
) WHERE round( total_bad / (total_good + total_bad) * 100) >= 20
ORDER BY REPORT;

您试图将CASE的两个不同语法混合在一起

在一种语法中,CASE关键字后面紧跟第一个WHEN子句,每个WHEN子句都有一个完整的布尔表达式进行计算,例如:

CASE WHEN pct >= 20 THEN ...
在另一种语法中,CASE关键字后面紧跟着一个被计算的标量表达式;每个WHEN子句都有一个标量值,要根据第一个表达式的结果测试是否相等,例如:

CASE pct WHEN 20 THEN ...
您试图使用第二种语法,但为WHEN子句提供了一个(部分)布尔表达式。你不能这么做

我认为最好的解决方案是简单地使用第一种语法。也就是说,当pct>=20时,你在写
案例pct,然后…
,而不是当pct>=20时,写
案例…
。这一点很清楚,允许您任意地进行复杂的案例陈述

如果您真的喜欢使用第二种类似开关的语法,那么在某些情况下,您可以想出一种方法将您想要的测试转换为相等测试。例如,您可以写:

CASE SIGN(pct-0.20) WHEN -1 THEN NULL ELSE 1 END

但我觉得这比用另一种方式写的更不清楚。

你试图混合CASE的两种不同语法

在一种语法中,CASE关键字后面紧跟第一个WHEN子句,每个WHEN子句都有一个完整的布尔表达式进行计算,例如:

CASE WHEN pct >= 20 THEN ...
在另一种语法中,CASE关键字后面紧跟着一个被计算的标量表达式;每个WHEN子句都有一个标量值,要根据第一个表达式的结果测试是否相等,例如:

CASE pct WHEN 20 THEN ...
您试图使用第二种语法,但为WHEN子句提供了一个(部分)布尔表达式。你不能这么做

我认为最好的解决方案是简单地使用第一种语法。也就是说,当pct>=20时,你在写
案例pct,然后…
,而不是当pct>=20时,写
案例…
。这一点很清楚,允许您任意地进行复杂的案例陈述

如果您真的喜欢使用第二种类似开关的语法,那么在某些情况下,您可以想出一种方法将您想要的测试转换为相等测试。例如,您可以写:

CASE SIGN(pct-0.20) WHEN -1 THEN NULL ELSE 1 END

但我觉得这比用另一种方式写的更不清楚。

如果你把你的案例改为:“,那么pct>=20时的案例……”如果你把你的案例改为:“,那么pct>=20时的案例……”这会起作用。请看我对你问题评论中附加问题的回答。这里给我们大家上了一课。。。需求规格说明可能很棘手,即使是最简单的问题!我们每个人对同一个问题都有不同的解释。在这种情况下,我只是碰巧猜对了。但后来我又在猜测自己,当时我想知道您想要的是“每行错误计数>=具有相同报告值的所有行总计数的20%”。请参阅我对您问题的评论中的附加问题的回答。这里给我们大家上了一课。。。需求规格说明可能很棘手,即使是最简单的问题!我们每个人对同一个问题都有不同的解释。在这种情况下,我只是碰巧猜对了。但后来我又在猜测自己,当时我想知道你想要的是“每行错误计数>=具有相同报告值的所有行总计数的20%”。如果问题的解释正确,分析在这里就没有帮助。如果问题的解释正确,分析在这里就没有帮助。