2014-01-24 2 views
4

У меня есть две таблицы следующим образом:Имя столбца на колонке с заголовком и сосчитать/кронштейне на основе метки столбца в другой таблице

TABLE 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; 

Я не понимаю, как я могу идти вперед и pivot результаты запроса 2 с запросом один. Я могу идти в неправильном направлении, но у меня нет идеи.

+0

В долгосрочной перспективе, вы, вероятно, будет гораздо лучше обслуживаться в дальнейшем нормализации ваших данных; повторяющиеся столбцы часто являются признаком недостатков дизайна. –

+0

@ Clockwork-Muse. Иногда мы все обязаны жить с вещами, как они, не меняя их, не так ли? Это одно из тех случаев для меня. – Rachcha

ответ

0

Я нашел ответ. Вы можете пропустить КТР и проверьте главный запрос в следующем:

/* -- 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; 

ВЫВОД:

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

Смежные вопросы