Как дважды использовать оператор GROUP BY в одном операторе SQL?

#sql #oracle

#sql #Oracle

Вопрос:

У меня есть следующий SQL-запрос:

 SELECT CourseId, DateOfCourseCompletion, COUNT(DISTINCT EmployeeId) FROM tblTestsTakenByEmployee ttbe
    INNER JOIN tblCoursesTakenByEmployee ctbe USING (ctbe.EmployeeId)
    WHERE ctbe.HasCompletedCourse = 'Y'
    GROUP BY ctbe.CourseId, ctbe.DateOfCourseCompletion, ctbe.EmployeeId
    HAVING AVG(ttbe.GivenMark) > 50
    ORDER BY ctbe.CourseId, ctbe.DateOfCourseCompletion;
 

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

Однако теперь я хочу подсчитать количество сотрудников с отметкой больше 50, которые прошли один и тот же курс в один и тот же день. Я предполагаю, что вы не можете снова использовать GROUP BY, поскольку оператор уже использовался для группировки всех тестов, которые сотрудник выполнил на данном курсе. Как бы я сгруппировал это без использования оператора GROUP BY?

Комментарии:

1. Когда запрос соединяет таблицы, очень важно добавлять перед именем каждого столбца имя таблицы или псевдоним таблицы. Для вас может быть очевидно, откуда берется каждый столбец, но это не для нас.

2. Самый простой и эффективный способ — сделать ваш первый запрос вложенным запросом. Затем во внешнем запросе выберите из подзапроса.

Ответ №1:

Используйте подход с подзапросом — внешним запросом, что-то вроде этого (не тестировалось):

 select courseid, dateofcoursecompletion, count(employeeid) as employee_count
from   (
         select courseid, dateofcoursecompletion, employeeid
         from   tblteststakenbyemployee ttbe
                inner join tblcoursestakenbyemployee ctbe using (employeeid)
         where  ctbe.hascompletedcourse = 'Y'
         group  by courseid, dateofcoursecompletion, employeeid
         having avg(givenmark) > 50
       )
group  by courseid, dateofcoursecompletion
order  by courseid, dateofcoursecompletion
;
 

Обратите внимание, что вам не нужно указывать distinct в количестве сотрудников. Агрегирование в подзапросе создает отдельные тройки (courseid, dateofcompletion, employeeid) , поэтому во внешнем запросе в каждой группе (courseid, dateofcompletion) идентификаторы сотрудников уже различны.