我正在尝试找一张能够显示学生每月出勤详情的表格。
我所拥有的是一个根据学生课程负荷总结缺勤数量的支点。
比方说,我知道这个学生一直有4节课,无论是学年还是学期,this would work perfectly:
SELECT * FROM
(SELECT SCHOOL_YEAR, TO_CHAR(CALENDAR_DATE, 'mon') MNTH, ATTENDANCE_CODE
FROM PERIOD_ATTENDANCE
WHERE PERSON_ID = '1234'
AND SCHOOL_CODE IN ('ESS', 'ASS', 'BSS')
)
PIVOT (SUM(CASE WHEN ATTENDANCE_CODE = 'L' THEN 1 END) as L,
SUM(CASE WHEN ATTENDANCE_CODE = 'A'
AND MNTH IN ('sep', 'oct', 'nov', 'dec', 'jan')
THEN 1/4
WHEN ATTENDANCE_CODE = 'A'
AND MNTH IN ('feb', 'mar', 'apr', 'may', 'jun')
THEN 1/4 END) as A
FOR MNTH
IN (
'sep',-- AS SEPTEMBRE,
'oct',-- AS OCTOBRE,
'nov',-- AS NOVEMBRE,
'dec',-- AS DECEMBRE,
'jan', -- AS JANVIER,
'feb',-- AS FÉVRIER,
'mar',-- AS MARS,
'apr',-- AS AVRIL,
'may',-- AS MAI,
'jun'-- AS JUIN
) -- END <IN>
) -- END PIVOT
但由于有些学生每学期学习的课程少于或多于平均4门课程,我需要找到一种方法,使“4”(“THEN 1/4 END
”)代表学生的实际课程数量正在服用。
我想出了一个返回这个数字的函数,但是一旦我将它插入到数据透视表中,查询只返回一行,它显示了每年学生缺勤的总和。
PIVOT (SUM(CASE WHEN ATTENDANCE_CODE = 'L' THEN 1 END) as L,
SUM(CASE WHEN ATTENDANCE_CODE = 'A'
AND MNTH IN ('sep', 'oct', 'nov', 'dec', 'jan')
THEN 1/PKG_PROFILE_ÉLÈVE.GET_COURSE_COUNT(SCHOOL_YEAR, '123456789', 1)
WHEN ATTENDANCE_CODE = 'A'
AND MNTH IN ('feb', 'mar', 'apr', 'may', 'jun')
THEN 1/PKG_PROFILE_ÉLÈVE.GET_COURSE_COUNT(SCHOOL_YEAR, '123456789', 2) END) as A
它返回以下内容,您会注意到school_year
列也已消失。
'sep'_L 'sep'_A 'oct'_L 'oct'_A 'nov'_L 'nov'_A 'dec'_L 'dec'_A 'jan'_L 'jan'_A 'feb'_L 'feb'_A 'mar'_L 'mar'_A 'apr'_L 'apr'_A 'may'_L 'may'_A 'jun'_L 'jun'_A
---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------
2 0.25 2 0.75 2 0.25 1 1.75 2 1 7 0.75 1 0.25 1 0.25 1 0.25
无论函数中的实际内容如何,都会发生这种情况。功能可以 简单如下,它仍将返回单个聚合行。
FUNCTION GET_COURSE_COUNT(A_SCHOOL_YEAR VARCHAR2, A_PERSON_ID VARCHAR2, A_SEMESTER VARCHAR2) RETURN NUMBER IS
NUM_COURSE NUMBER := NULL;
BEGIN
NUM_COURSE = 4;
RETURN NUM_COURSE;
END GET_COURSE_COUNT;
有人知道这是否是由于PIVOT功能本身引起的?函数是否以某种方式强制聚合和行的总和? 我现在已经看了两天了,我似乎无法找到这样的事情。它一定是显而易见的我错过了......
实际功能如下:
FUNCTION GET_COURSE_COUNT(A_SCHOOL_YEAR VARCHAR2, A_PERSON_ID VARCHAR2, A_SEMESTER VARCHAR2) RETURN NUMBER IS
NUM_COURSE NUMBER := NULL;
BEGIN
SELECT
COUNT( CASE --total des cours prit durant le semestre spécifié
WHEN SEMESTER = A_SEMESTER
THEN SEMESTER END) AS SEMESTRE INTO NUM_COURSE
FROM (SELECT DISTINCT SCT.SCHOOL_YEAR,
SCT.COURSE_CODE || '-' || SCT.COURSE_SECTION AS COURSE,
SC.TAKE_ATTENDANCE_FLAG, CM.SEMESTER
FROM SCHOOL_CLASSES SC, STUDENT_PROGRAM_CLASS_TRACKS SCT, CLASS_MEETINGS CM
WHERE SCT.PERSON_ID = A_PERSON_ID
AND SCT.SCHOOL_CODE IN ('ESS', 'ASS', 'BSS')
AND SC.SCHOOL_CODE = SCT.SCHOOL_CODE
AND SCT.SCHOOL_YEAR = A_SCHOOL_YEAR
AND SC.SCHOOL_YEAR = SCT.SCHOOL_YEAR
AND SC.CLASS_CODE = SCT.CLASS_CODE
AND SCT.SCHOOL_CODE = CM.SCHOOL_CODE
AND SCT.CLASS_CODE = CM.CLASS_CODE
AND CM.SCHOOL_YEAR = SCT.SCHOOL_YEAR
AND SCT.SCHOOL_YEAR_TRACK = CM.SCHOOL_YEAR_TRACK
AND SCT.DEMIT_INDICATOR NOT IN ('9')
ORDER BY SCT.SCHOOL_YEAR, CM.SEMESTER, COURSE);
RETURN NUM_COURSE;
END GET_COURSE_COUNT;
答案 0 :(得分:2)
请尝试此查询:
SELECT * FROM
(SELECT SCHOOL_YEAR, TO_CHAR(CALENDAR_DATE, 'MM') MNTH, ATTENDANCE_CODE,
GET_COURSE_COUNT(SCHOOL_YEAR, '123456789',
case when TO_CHAR(CALENDAR_DATE, 'MM') IN ('09','10','11','12','01')
then 1 else 2 end) gcc
FROM PERIOD_ATTENDANCE
WHERE PERSON_ID = '1234' AND SCHOOL_CODE IN ('ESS', 'ASS', 'BSS'))
PIVOT (
SUM(CASE WHEN ATTENDANCE_CODE = 'L' THEN 1 END) as L,
SUM(CASE WHEN ATTENDANCE_CODE = 'A' THEN 1/gcc END) as A
FOR MNTH IN ('09','10','11','12','01','02','03','04','05','06'))
我认为pivot子句中使用的每一列都是聚合的,在这种情况下,school_year
用作函数的参数,因此它也被聚合 -
所以解决方案应该是将函数移动到基础子查询。此外,当我从函数定义中删除此参数时,行未加入。
请使用您的数据和计算验证最终结果。