Oracle SQL - 如何将计数除以计数总和?

时间:2016-09-28 10:46:53

标签: sql oracle count sum divide

我的查询目前看起来像这样(简化)

 SELECT
       m.academicyr,
       m.ncyeargrp_format AS YEAR,
       Count(*) AS cohort,
       round (Avg (m.per_att),4) AS attendance,
       Round (per_cohort,4)      

   FROM
 (
   SELECT
         s.academy,
         s.academicyr,
         s.adno,
         s.ncyeargrp_format,
         CASE WHEN a.possible_att_marks = 0 THEN NULL
           ELSE (a.present_att_marks / a.possible_att_marks)
             END
               AS per_att,
         a.possible_att_marks,
         a.present_att_marks,
         a.period,
         Count (*) AS cohort,
         Count (*) / Sum(Count(*)) AS per_cohort

   FROM
      VACADEMY_STU_all  s

   LEFT JOIN
        vacademy_attendance a
       ON s.academy = a.academy
      AND s.adno = a.adno
      AND s.term = a.period
      AND s.academicyr = a.academicyr

   WHERE
          s.academy = 'CAN'
          AND s.academicyr = '1617'
          AND a.period = '1'

          GROUP BY
         s.academy,
         s.academicyr,
         s.adno,
         s.ncyeargrp_format,
         a.possible_att_marks,
         a.present_att_marks,
         a.period

  ) m
          GROUP BY
          m.academicyr,
          m.ncyeargrp_format,
          m.per_cohort

          ORDER BY
          To_Number(Trim(regexp_replace(m.ncyeargrp_format, '[A-Za-z]')))

我在这里尝试将计数*除以计数之和*。我收到错误'不是单个群组功能'。

如果没有' Round(Per_cohort,4)'该查询完全正常。在第一个选择中,也从内部选择和组中删除。

我期待的结果是

年龄组人数调查群体的比例 7年级126 18.18%98.10% 8年级139 20.06%93.88% 9年级143 20.63%90.56% 10年级143 20.63%95.94% 11年级142 20.49%88.45% 总计693 100.00%93.28%

我让所有其他列完美运行,我只需要百分比群组,因此群组列中的值除以使用count *创建的群组列的总数。

任何帮助都非常感激。

由于

2 个答案:

答案 0 :(得分:1)

如果这是得到错误的行:

     Count (*) / Sum(Count(*)) AS per_cohort

然后你可以通过使用窗口函数来解决这个问题:

     Count (*) / Sum(Count(*)) over () AS per_cohort

答案 1 :(得分:0)

WITH cte AS
(
    SELECT s.academy,
           s.academicyr,
           s.adno,
           s.ncyeargrp_format,
           CASE WHEN a.possible_att_marks = 0 THEN NULL
                ELSE (a.present_att_marks / a.possible_att_marks)
           END AS per_att,
           a.possible_att_marks,
           a.present_att_marks,
           a.period,
           COUNT(*) AS cohort
    FROM VACADEMY_STU_all s
    LEFT JOIN vacademy_attendance a
        ON s.academy = a.academy AND
           s.adno = a.adno AND
           s.term = a.period AND
           s.academicyr = a.academicyr
    WHERE s.academy = 'CAN' AND
          s.academicyr = '1617' AND
          a.period = '1'
    GROUP BY s.academy,
             s.academicyr,
             s.adno,
             s.ncyeargrp_format,
             a.possible_att_marks,
             a.present_att_marks,
             a.period
)

SELECT m.academicyr,
       m.ncyeargrp_format AS YEAR,
       m.cohort,
       ROUND(AVG(m.per_att), 4) AS attendance,
       ROUND(m.cohort / (SELECT SUM(cohort) FROM cte), 4)
FROM cte m
GROUP BY m.academicyr,
         m.ncyeargrp_format,
         m.per_cohort
ORDER BY TO_NUMBER(TRIM(REGEXP_REPLACE(m.ncyeargrp_format, '[A-Za-z]')))