2014-01-24 60 views
4

列標籤上我有兩個表如下/透視:列名和列標題和計算基於其他表

表marklist:

student_id class_id subject_1 subject_2 subject_3 subject_4 subject_5 
----------- ----------- ----------- ----------- ----------- ----------- ---------- 
1   9   78   87         95 
2   9   67   95         87 
3   9   85   84         85 
4   10   70      65   78  
5   10   75      80   81  
6   10   80      75   82  

表subject_names

column_name  subject_name 
--------------- ------------- 
subject_1  English 
subject_2  Chemistry 
subject_3  Economics 
subject_4  Accounts 
subject_5  Biology 

現在,我需要生成一個像這樣的報告class_id = 9

column_name  subject_name no_of_students 
--------------- ------------- -------------- 
subject_1  English  3 
subject_2  Chemistry  3 
subject_3  Economics  0 
subject_4  Accounts  0 
subject_5  Biology  3 

總之,我必須生成一個帶有column_names,subject_name和來自class_id = 9(或10,無論)的學生人數的報告。

所有我設法做的是

1.

SELECT sn.column_name, sn.subject_name FROM subject_names sn; 

2.

SELECT ml.class_id, 
      count(ml.subject_1) AS s1, 
      count(ml.subject_2) AS s1, 
      count(ml.subject_3) AS s1, 
      count(ml.subject_4) AS s1, 
      count(ml.subject_5) AS s1, 
     FROM marklist ml 
    WHERE ml.class_id = 9; 

我不明白我怎麼繼續前進,將查詢2的結果與查詢1一起傳送。我可能會走錯方向,但我不知道。

+0

從長遠來看,你很可能會被更好的進一步正常化您的數據服務;重複列往往是設計缺陷的標誌。 –

+0

@ Clockwork-Muse-有時候我們都有義務和事物一起生活,而不改變它們,是不是?這是我的一個時代。 – Rachcha

回答

0

我找到了答案。你可以跳過CTE和檢查主查詢出以下幾點:

/* -- This WITH clause is just for your reference. 
WITH marklist AS (
SELECT 1 student_id, 9 class_id, 78 subject_1,87 subject_2, 
     null subject_3, null subject_4, 95 subject_5 FROM dual 
UNION ALL SELECT 2, 9, 67,95, null, null, 87 FROM dual 
UNION ALL SELECT 3, 9, 85,84, null, null, 85 FROM dual 
UNION ALL SELECT 4, 10,70, null, 65,78, null FROM dual 
UNION ALL SELECT 5, 10,75, null, 80,81, null FROM dual 
UNION ALL SELECT 6, 10,80, null, 75,82, null FROM dual 
) 
, subject_names AS (
SELECT 'subject_1' column_name, 'English' subject_name FROM dual 
UNION ALL SELECT 'subject_2', 'Chemistry' FROM dual 
UNION ALL SELECT 'subject_3', 'Economics' FROM dual 
UNION ALL SELECT 'subject_4', 'Accounts' FROM dual 
UNION ALL SELECT 'subject_5', 'Biology' FROM dual 
) -- */ 
SELECT sn.column_name, sn.subject_name, 
     (SELECT COUNT(CASE sn.column_name 
         WHEN 'subject_1' THEN ml.subject_1 
         WHEN 'subject_2' THEN ml.subject_2 
         WHEN 'subject_3' THEN ml.subject_3 
         WHEN 'subject_4' THEN ml.subject_4 
         WHEN 'subject_5' THEN ml.subject_5 
         END) 
      FROM marklist ml 
      WHERE ml.class_id = 9) AS no_of_students 
    FROM subject_names sn; 

OUTPUT:

column_name subject_name no_of_students 
-------------- --------------- -------------- 
subject_1  English   3 
subject_2  Chemistry  3 
subject_3  Economics  0 
subject_4  Accounts  0 
subject_5  Biology   3 
2

您可以unpivot您marklist表外與subject_names表加入。

with unpivot_x(student_id,class_id,subject_code,marks) as (
    select * from marklist 
    unpivot (marks for subject_code in ( subject_1 as 'subject_1', 
              subject_2 as 'subject_2', 
              subject_3 as 'subject_3', 
              subject_4 as 'subject_4', 
              subject_5 as 'subject_5' 
            ) 
            )) 
select a.column_name,a.subject_name, count(b.student_id) 
    from subject_names a left outer join unpivot_x b 
    on a.column_name = b.subject_code and b.class_id = 9 
group by a.column_name,a.subject_name 
order by 1; 

演示在sqlfiddle

+0

你的答案絕對有用,但我在你發佈之前已經找到了一個解決方案。不管怎麼說,多謝拉。 – Rachcha

0

試試這個

SELECT a.column_name, a.subject_name, COUNT(subject_1) 
FROM subject_names a 
JOIN mark_list b ON b.class_id =9 
AND a.subject_name = 'English' 
GROUP BY a.subject_name 
UNION ALL SELECT a.column_name columnname, a.subject_name, COUNT(subject_3) 
FROM subject_names a 
JOIN mark_list b ON b.class_id =9 
AND a.subject_name = 'Chemistry' 
GROUP BY a.subject_name 
UNION ALL SELECT a.column_name columnname, a.subject_name, COUNT(subject_4) 
FROM subject_names a 
JOIN mark_list b ON b.class_id =9 
AND a.subject_name = 'Economics' 
GROUP BY a.subject_name UNION ALL 
SELECT a.column_name columnname, a.subject_name, COUNT(subject_2) 
FROM subject_names a 
JOIN mark_list b ON b.class_id =9 
AND a.subject_name = 'Accounts' 
GROUP BY a.subject_name 
UNION ALL 
SELECT a.column_name columnname, a.subject_name, COUNT(subject_1) 
FROM subject_names a 
JOIN mark_list b ON b.class_id =9 
AND a.subject_name = 'Biology' 
GROUP BY a.subject_name 
+0

感謝您的努力,但您是否閱讀過我的答案? – Rachcha

+0

如何?你說什麼基礎? – Rachcha

+0

用於連接以檢索結果。 – abinaya