如何正确使用组最大?

时间:2018-05-21 06:38:50

标签: sql oracle group-by having

我正在尝试使用group by

找到计数的最大值

第一个代码:

 SELECT MAX (COUNT (studid)) AS total,
         unitcode,
         semester,
         TO_CHAR (ofyear, 'yyyy') AS "Year of Offer"
    FROM uni.enrolment
   WHERE TO_CHAR (ofyear, 'YYYY') = '2013'
GROUP BY semester, ofyear, unitcode
ORDER BY total;

结果:

  

ORA-00937:不是单组组功能       00937. 00000 - “不是单组小组的功能”       *原因:
      *行动:       行错误:18列:36

第二段代码:

  SELECT unitcode,
         TO_CHAR (ofyear, 'YYYY') AS year,
         semester,
         COUNT (studid) AS student_count
    FROM uni.enrolment
GROUP BY unitcode, ofyear, semester
  HAVING COUNT (studid) = (  SELECT MAX (COUNT (studid))
                               FROM uni.enrolment
                           GROUP BY unitcode, ofyear, semester
                             HAVING TO_CHAR (ofyear, 'YYYY') = '2013')
ORDER BY unitcode;

结果:

╔════════════════════════════════════════════════╗
║ UNITCODE    YEAR     SEMESTER    STUDENT_COUNT ║
╠════════════════════════════════════════════════╣
║ EG2004      2013     1           8             ║
╚════════════════════════════════════════════════╝

当我运行第一个代码时,它给了我一个错误,但第二个代码完美无缺。我真的不明白这个错误。为什么我必须使用子查询来解决它?

2 个答案:

答案 0 :(得分:1)

嵌套聚合函数是Oracle主义。我个人觉得它们很混乱。但MAX(COUNT( . . . ))与:

相同
select max(cnt)
from (select . . . , count(<something>) as cnt
      from t
      group by . . .
     ) x;

也就是说,它会进行两次聚合,一次是group by,另一次没有。外部的一个不能返回未聚合的列。这就是你收到错误的原因。

我想要注意的是,对于第二个查询,您需要在内部和外部过滤年份。因此,查询可能会返回正确的结果,但您希望这样做:

SELECT unitcode, TO_CHAR(ofyear, 'YYYY') AS year, semester,
       COUNT(studid) AS student_count
FROM uni.enrolment
WHERE TO_CHAR(ofyear, 'YYYY') = '2013')
GROUP BY unitcode, TO_CHAR(ofyear, 'YYYY'), semester
HAVING COUNT(studid) = (SELECT MAX (COUNT (studid))
                        FROM uni.enrolment
                        GROUP BY unitcode, ofyear, semester
                        HAVING TO_CHAR(ofyear, 'YYYY') = '2013'
                       )
ORDER BY unitcode;

请注意,我还将表达式放在GROUP BY year中。您希望按年份汇总,而不是按原始日期汇总。

答案 1 :(得分:0)

您需要先计算计数,然后才能确定哪些是最大值或相等的最大值。我建议第二步使用RANK() OVER()DENSE_RANK() OVER();其中这个等于1的结果(当订购DESC时)你有最大的计数。在此查询中,窗口函数将在GROUP BY之后作为SELECT子句的一部分处理(select子句不是第一次处理的),因此COUNT()可用作排名的输入。

SELECT
        total
      , unitcode
      , semester
      , ofyear
FROM (
      SELECT
              count(studid) AS total
            , unitcode
            , semester
            , to_char(ofyear, 'yyyy') AS "Year of Offer"
            , dense_rank() OVER (ORDER BY count(studid) DESC) AS rnk
      FROM uni.enrolment
      WHERE to_char(ofyear, 'YYYY') = '2013'
      GROUP BY
              semester
            , ofyear
            , unitcode
      ) d
WHERE rnk = 1 --<< this is how we only list the maximum(s)
ORDER BY
        unitcode
      , semester
;

另请注意,您可以使用EXTRACT(YEAR FROM ofyear)而不是使用to_char