Страницы

четверг, 21 ноября 2013 г.

Запросы к базе данных Деканат

Минимальный список характеристик:
  • Код группы, курс, количество студентов, общий объем часов;
  • ФИО преподавателя, вид контроля, дата;
  • Название дисциплины, категория, объем часов.
Одна группа изучает несколько дисциплин и одна дисциплина может преподаваться нескольким группам.
Категория дисциплины - гуманитарная, математическая, компьютерная, общеинженерная и т.д.
Вид контроля - зачет, экзамен.
Выборки:  
  • Для каждой группы определить продолжительность сессии.  
  • Определить преподавателя, который в сессию принимает экзамены (не зачеты) у наибольшего числа студентов. 
  • Определить, какой процент от общего объема дисциплин, изучаемых группой 'АП-17а', составляют дисциплины каждой категории. 
  • Определить, не сдает ли какая-либо группа два экзамена в один день.
Несложный вариант, надо сказать. Делаем таблицы-справочники групп, преподавателей и дисциплин. Связываем их все через таблицу «Контроль», куда будем заносить зачеты и экзамены, сдаваемые группами. Поскольку в одном из запросов нужно посчитать продолжительность сессии, добавляем в таблицу групп поля «Начало_сессии» и «Окончание_сессии». В общем, получается вот такая схема:


1. Считаем для каждой группы продолжительность сессии.
Для этого достаточно одной таблицы «Группы», из которой берем код группы и делаем вычисляемое поле «Продолжительность сессии». Продолжительность считаем как разность в днях между датами начала и окончания с помощью функции DateDiff.


SELECT Группы.Код_группы, DateDiff('d',[Группы]![Начало_сесии],[Группы]![Окончание_сессии]) AS [Продолжительность сессии]
FROM Группы;
2. Нужно определить самого нагруженного экзаменатора. Для выборки делаем три запроса
В первом делаем группировку по преподавателям, ставим как условие «вид контроля» - «экзамен», суммируем количество студентов по каждому преподавателю.


SELECT Преподаватели.ФИО, Sum(Группы.Количество_студентов) AS [Sum-Количество_студентов]
FROM Преподаватели INNER JOIN (Группы INNER JOIN Контроль ON Группы.Код_группы = Контроль.Группа) ON Преподаватели.Код = Контроль.Преподаватель
WHERE (((Контроль.Вид_контроля)="Экзамен"))
GROUP BY Преподаватели.ФИО;
Во втором запросе выбираем максимальное количество студентов, которое было принято преподавателями.


SELECT Max(Экзамен_макс1.[Sum-Количество_студентов]) AS [Max-Sum-Количество_студентов]
FROM Экзамен_макс1;
В третьем запросе выбираем тех преподавателей, которые приняли максимальное число студентов на экзаменах.


SELECT Экзамен_макс1.ФИО, Экзамен_макс1.[Sum-Количество_студентов]
FROM Экзамен_макс1, Экзамен_макс2
WHERE (((Экзамен_макс1.[Sum-Количество_студентов])=[Экзамен_макс2]![Max-Sum-Количество_студентов]));

3. Считаем процент дисциплин каждой категории от общего объема дисциплин для группы АП-17а.
Делаем запрос с группировкой, группируем по группе (и отбираем нужную группу) и по категории. Считаем суммарный объем часов по каждой категории и высчитываем процент от общего объема часов группы (указанных в таблице «Группы»).
Получается такой запрос


SELECT Группы.Код_группы, Дисциплины.Категория, Sum(Дисциплины.[Объем часов]) AS [Sum-Объем часов], [Sum-Объем часов]*100/[Объем_часов] AS Процент
FROM Дисциплины INNER JOIN (Группы INNER JOIN Контроль ON Группы.Код_группы = Контроль.Группа) ON Дисциплины.Код = Контроль.Дисциплина
GROUP BY Группы.Код_группы, Дисциплины.Категория, Группы.Объем_часов
HAVING (((Группы.Код_группы)="АП-17а"));
4 Смотрим накладки (совпадение экзаменов в один день у всех групп)
Группируем по группе и по дате, суммируем количество экзаменов за каждый день, отбираем те записи, в которых это количество больше 1.


SELECT Группы.Код_группы, Контроль.Дата, Count(Контроль.Код_записи) AS [Count-Код_записи]
FROM Дисциплины INNER JOIN (Группы INNER JOIN Контроль ON Группы.Код_группы = Контроль.Группа) ON Дисциплины.Код = Контроль.Дисциплина
WHERE (((Контроль.Вид_контроля)="Экзамен"))
GROUP BY Группы.Код_группы, Контроль.Дата
HAVING (((Count(Контроль.Код_записи))>1));
Вот и все, кажется.