如何最大限度地正确使用group by?
How to use group by correctly in maximum?
我正在尝试使用 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: not a single-group group function
00937. 00000 - "not a single-group group function"
*Cause:
*Action:
Error at Line: 18 Column: 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 ║
╚════════════════════════════════════════════════╝
当我 运行 第一个代码时,它给我一个错误,但第二个代码完美无缺。我真的不明白这个错误。为什么一定要用子查询来解决呢?
您需要先计算计数,然后才能确定其中的最大值或等于最大值。我建议在第二步使用 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
嵌套聚合函数是 Oracle 主义。我个人觉得他们相当混乱。但是 MAX(COUNT( . . . ))
等同于:
select max(cnt)
from (select . . . , count(<something>) as cnt
from t
group by . . .
) x;
也就是说,它进行两种聚合,一种带有 group by
,一种不带。外部不能 return 未聚合列。这就是您收到错误的原因。
我要注意,对于您的第二个查询,您需要过滤内部和外部的年份。所以查询可能恰好return正确的结果,但是你想做的是:
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;
请注意,我还将 year
的表达式放在 GROUP BY
中。您希望按年份而不是原始日期进行汇总。
我正在尝试使用 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: not a single-group group function 00937. 00000 - "not a single-group group function" *Cause:
*Action: Error at Line: 18 Column: 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 ║
╚════════════════════════════════════════════════╝
当我 运行 第一个代码时,它给我一个错误,但第二个代码完美无缺。我真的不明白这个错误。为什么一定要用子查询来解决呢?
您需要先计算计数,然后才能确定其中的最大值或等于最大值。我建议在第二步使用 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
嵌套聚合函数是 Oracle 主义。我个人觉得他们相当混乱。但是 MAX(COUNT( . . . ))
等同于:
select max(cnt)
from (select . . . , count(<something>) as cnt
from t
group by . . .
) x;
也就是说,它进行两种聚合,一种带有 group by
,一种不带。外部不能 return 未聚合列。这就是您收到错误的原因。
我要注意,对于您的第二个查询,您需要过滤内部和外部的年份。所以查询可能恰好return正确的结果,但是你想做的是:
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;
请注意,我还将 year
的表达式放在 GROUP BY
中。您希望按年份而不是原始日期进行汇总。