2015-05-28 72 views
2

我想要獲得一張表格,顯示學生每月的出勤詳情。
我擁有的是一個根據學生的課程負荷總結缺勤數量的關鍵。
例如說我知道這個學生有4個班,所有的時間,學年或學期不分,this would work perfectlyOracle SQL PIVOT:缺少列和聚合行?

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

那麼你想計算出每個人每月的出勤率,並確定月份?出席專欄中的「A」和「L」是什麼? – Koshinae

+0

A代表缺席,L代表缺席。因此,Jan_A是該學年所有1月份缺勤總數(其中缺席應該等於缺勤/學生正在上課的班數),而Jan_L則是該學生1月份的所有缺勤。 (Lates在period_attendance表中只記錄爲1個最新記錄,希望能夠澄清一些事情 – Roxanne

+0

你怎麼知道一個人有多少班?這是'school_code'? – Koshinae

回答

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用作函數的參數,因此它也被聚合 - 因此解決方案應該將函數移到基本子查詢中。另外,當我從函數定義中刪除這個參數行時沒有加入。

請驗證您的數據和計算的最終結果。

+0

非常感謝,解決了這個問題,這是一個非常優雅的解決方案。 – Roxanne