我正在尝试使用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 ║
╚════════════════════════════════════════════════╝
当我运行第一个代码时,它给了我一个错误,但第二个代码完美无缺。我真的不明白这个错误。为什么我必须使用子查询来解决它?
答案 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