powered by simpleCommunicator - 2.0.52     © 2025 Programmizd 02
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Агрегирующая функция совместно с having или where?
6 сообщений из 6, страница 1 из 1
Агрегирующая функция совместно с having или where?
    #39755259
Dmi_tri
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Имеется таблица EXAM_MARKS(EXAM_ID, STUDENT_ID, SUBJ_ID, MARK, EXAM_DATE), в которой занесена информация об оценках на экзаменах. (SUBJ_ID - название предмета, смысл остальных атрибутов ясен из названия). Требуется определить количество предметов обучения
с оценкой, превышающей среднее значение оценки студента с идентификатором 301.

Написал следующий запрос:
SELECT COUNT(subj_id)
FROM exam_marks
HAVING mark>(SELECT AVG(mark) FROM exam_marks GROUP BY student_id HAVING student_id=301);

workbench выдает ошибку "Error code 1054: Unknown column 'mark' in 'having clause'"

При замене HAVING mark на WHERE mark программа выдает результат (не знаю насколько корректный)

Отсюда несколько вопросов:
1. Почему первоначальный запрос не запускается?
2. Почему второй запрос отрабатывает, ведь с агрегирующими функциями запрещено использовать where?
3. Не уверен в корректности подзапроса - SELECT AVG(mark) FROM exam_marks GROUP BY student_id. В данном случае произведена группировка по атрибуту student_id, хотя в условие выборки SELECT занесено только AVG(mark). Читал, что при группировке GROUP BY все условия группировки должны также выноситься и в SELECT. То есть, как мне кажется, корректным в данном случае было бы написать SELECT student_id, AVG(mark) FROM exam_marks GROUP BY student_id. Но в данном случае workbench выдает "Error code: 1241. Operand should contain 1 column"
...
Рейтинг: 0 / 0
Агрегирующая функция совместно с having или where?
    #39755271
Фотография полудух
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: sql
1.
2.
3.
SELECT subj_id, mark
FROM exam_marks
WHERE mark > (SELECT avg(mark) FROM exam_marks WHERE student_id = 301)
...
Рейтинг: 0 / 0
Агрегирующая функция совместно с having или where?
    #39755290
Dmi_tri
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
полудух
Код: sql
1.
2.
3.
SELECT subj_id, mark
FROM exam_marks
WHERE mark > (SELECT avg(mark) FROM exam_marks WHERE student_id = 301)



будем считать, что вопрос про количество вы не заметили
но! с агрегирующими функциями запрещено использовать where
...
Рейтинг: 0 / 0
Агрегирующая функция совместно с having или where?
    #39755291
Dmi_tri
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
The HAVING clause was added to SQL because the WHERE keyword could not be used with aggregate functions .

(c) https://www.w3schools.com/sql/sql_having.asp
...
Рейтинг: 0 / 0
Агрегирующая функция совместно с having или where?
    #39755296
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dmi_tri,

В предложенном вам запросе нет агрегирующей функции в секции WHERE.
...
Рейтинг: 0 / 0
Агрегирующая функция совместно с having или where?
    #39755297
Фотография полудух
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
будем считать, что вы не умеете говорить спасибо.
счётчик сами сумеете вставить, не всё же для вас разжёвывать.
HAVING нужно понимать правильно:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
-- Мы получаем те же результаты, но только для тех городов, где все значения temp_lo меньше 40.
Наконец, если нас интересуют только города, названия которых начинаются с "S", мы можем сделать:
SELECT city, max(temp_lo)
FROM weather
WHERE city LIKE 'S%'(1)
GROUP BY city
HAVING max(temp_lo) < 40;

Важно понимать, как соотносятся агрегатные функции и SQL-предложения WHERE и HAVING.
Основное отличие WHERE от HAVING заключается в том, что WHERE сначала выбирает строки, а затем группирует их и вычисляет агрегатные функции
(таким образом, она отбирает строки для вычисления агрегатов), тогда как HAVING отбирает строки групп ПОСЛЕ группировки и вычисления агрегатных функций.
Как следствие, предложение WHERE не должно содержать агрегатных функций;
не имеет смысла использовать агрегатные функции для определения строк для вычисления агрегатных функций..
Предложение HAVING, напротив, всегда содержит агрегатные функции. (Строго говоря, вы можете написать предложение HAVING, не используя агрегаты,
но это редко бывает полезно. То же самое условие может работать более эффективно на стадии WHERE.)

В предыдущем примере мы смогли применить фильтр по названию города в предложении WHERE, так как названия не нужно агрегировать.
Такой фильтр эффективнее, чем дополнительное ограничение HAVING, потому что с ним не приходится группировать и вычислять агрегаты для всех строк,
не удовлетворяющих условию WHERE.


-- в этом ГЛАВНАЯ ЗАТЕЯ: агрегатная ф-я в HAVING, которая СНАЧАЛА посчитает, а потом получившиеся результаты можно просеять через HAVING.
SELECT x, sum(y) FROM test1 GROUP BY x HAVING sum(y) > 3; -- оставит в итоге только >3
SELECT cid FROM jobs GROUP BY cid HAVING sum(closed=0)=0;
...
Рейтинг: 0 / 0
6 сообщений из 6, страница 1 из 1
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Агрегирующая функция совместно с having или where?
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]