| imho.ws |
![]() |
|
|
|
# 1 |
|
Guest
Сообщения: n/a
|
Помогите пожалуйста сделать такой SQL запрос: надо высчитать максимальное среднее значение по определеному столбцу, знаю как найти максимальное значение, знаю как найти среднее, но как это вмести объединить? В книжках и мануалах прочитал только что вложеных агрегатных запросов делать незя, но ни где не нашел как решить эту проблему.
|
|
|
# 2 |
|
::VIP::
Регистрация: 12.11.2002
Адрес: Nicosia, Cyprus
Сообщения: 1 285
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
Дык вроде среднее значение по определению одно - что ты понимаешь под "максимальным средним"?
__________________
"If people only knew how hard I work to gain my mastery, it wouldn't seem so wonderful at all." Michelangelo Buonarroti |
|
|
|
|
# 3 |
|
::VIP::
Регистрация: 19.03.2004
Сообщения: 1 329
![]() ![]() ![]() ![]() |
«Максимальное среднее» высчитывается обычно за несколько периодов или итераций, т.е. просто берется максимум среди средних значений за каждый период (итерацию). Сразу по всему столбцу данных же можно вычислить только одно среднее. Задача видимо требует уточнения условия.
|
|
|
|
|
# 4 |
|
Guest
Сообщения: n/a
|
да виноват не корректно задал вопрос, а дело вот в чем у меня вот такие 3 таблицы, нарисовал как мог :) , -- – внешний ключ
Код:
таблица: ГРУППА СТУДЕНТ ЭКЗАМЕН
поля: имя кафедры идентификатор---------идентификатор
номер группы-------номер группы оценка
фамилия студента
|
|
|
# 5 |
|
::VIP::
Звезда первого сезона Молчун-2004 Регистрация: 24.08.2002
Сообщения: 1 575
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
Вот до чего дошел я:
Код:
SELECT s.stud_id stud_id, cath_id, avgm FROM student s, (SELECT stud_id, AVG(mark) avgm FROM exam_marks GROUP BY stud_id) a WHERE s.stud_id = a.stud_id; З.Ы. Кстати, на чем пишешь? Если на Oracle (как и я), то может стоит заколбасить процедурку на PL/SQL?
__________________
Действовать надо тупо и это лучшее доказательство нашей чистоты и силы! Последний раз редактировалось Ghost; 05.05.2005 в 08:09. Причина: чертов Сайгон... |
|
|
|
|
# 6 | |
|
Guest
Сообщения: n/a
|
[QUOTE=Ghost]Вот до чего дошел я:[CODE]
SELECT s.stud_id stud_id, cath_id, avgm FROM student s, Цитата:
.Может я что-то недопонял, но по моему то что ты написал чуть-чуть не то т.к. необходимо найти на каждой кафедре студента с наибольшим средним балом, то отсюда следует, что надо группировать именно по полю имя кафедры а не по каким либо другим, потому что на одной кафедре могут быть (и есть) разные группы, а уже потом в каждой группу выбирать максимальный средний бал. Если бы можно делать вложенный агрегатные запросы, то это выглядело наверно так : Код:
SELECT Группа.Кафедра, Студент.Фамилия, Max(Avg(Экзамен.Оценка) AS [Avg-Оценка]) FROM (Группа INNER JOIN Студент ON Группа.[Номер группы]=Студент.[Номер группы]) INNER JOIN Экзамен ON Студент.Идентификатор=Экзамен.[Идентификатор студента] GROUP BY Группа.Кафедра; Я пытался делать с вложенными запросами : Код:
SELECT Группа.Кафедра, Студент.Фамилия, Avg(Экзамен.Оценка) AS [Avg-Оценка]
FROM (Группа INNER JOIN Студент ON Группа.[Номер группы]=Студент.[Номер группы]) INNER JOIN Экзамен ON Студент.Идентификатор=Экзамен.[Идентификатор студента]
GROUP BY Группа.Кафедра, Студент.Фамилия
HAVING Max (
SELECT Avg(Экзамен.Оценка) AS [Avg-Оценка] FROM (Группа INNER JOIN Студент ON Группа.[Номер группы]=Студент.[Номер группы]) INNER JOIN Экзамен ON Студент.Идентификатор=Экзамен.[Идентификатор студента]
GROUP BY Группа.Кафедра
);
Так что я все сижу и думаю как сделать эту хрень...... |
|
|
|
# 7 |
|
Junior Member
Регистрация: 15.05.2002
Сообщения: 168
![]() ![]() ![]() ![]() ![]() |
А вот такие штучки а Accesse можно?
Код:
select k.kafedra, k.student, k.avgrade from ( select G.K kafedra, S.SNAME student, AVG(E.GRADE) avgrade from G join S on G.NG=S.GN join E on S.S=E.S group by G.K, S.SNAME) k where (k.kafedra, k.avgrade) in ( select m.kafedra, MAX(m.avgrade) from ( select G.K kafedra, AVG(E.GRADE) avgrade from G join S on G.NG=S.GN join E on S.S=E.S group by G.K) m group by m.kafedra ) Код:
SELECT Группа.Кафедра, Студент.Фамилия, Max(Avg(Экзамен.Оценка) AS [Avg-Оценка]) FROM (Группа INNER JOIN Студент ON Группа.[Номер группы]=Студент.[Номер группы]) INNER JOIN Экзамен ON Студент.Идентификатор=Экзамен.[Идентификатор студента] GROUP BY Группа.Кафедра;
__________________
"Да, человек смертен, но это было бы еще полбеды. Плохо то, что он иногда внезапно смертен, вот в чем фокус!" Михаил Булгаков. Мастер и Маргарита Последний раз редактировалось Kiva; 05.05.2005 в 14:58. |
|
|
|
|
# 8 |
|
::VIP::
Звезда первого сезона Молчун-2004 Регистрация: 24.08.2002
Сообщения: 1 575
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
Интересная задачка. Самому стало интересно. Сделал финт ушами: объеденил средний балл и номер студента в одно поле с разделителем ",," - максимально ищется нормально, остается только его разбить на части. У меня, правда, таблицы несколько отличаются:
Код:
CREATE TABLE UNIVERSITY ( UNIV_ID INTEGER PRIMARY KEY, UNIV_NAME CHAR(96) NOT NULL UNIQUE, RATING INTEGER, CITY CHAR(20) NOT NULL ); CREATE TABLE STUDENT ( STUD_ID INTEGER PRIMARY KEY, SURNAME CHAR(20) NOT NULL, NAME CHAR(20) NOT NULL, STIPEND INTEGER, KURS INTEGER NOT NULL, CITY CHAR(20) NOT NULL, BIRTHDAY DATE, UNIV_ID INTEGER REFERENCES UNIVERSITY(UNIV_ID) ); CREATE TABLE EXAM_MARKS ( EXAM_ID INTEGER PRIMARY KEY, STUD_ID INTEGER REFERENCES STUDENT(STUD_ID), SUBJ_ID INTEGER REFERENCES SUBJECT(SUBJ_ID), MARK INTEGER, EXAM_DATE DATE, CHECK ((MARK>=2) AND (MARK<=5)) ); Код:
select univ_id, substr(csm, 1, instr(csm, ',,') - 1) maxmark, substr(csm, instr(csm, ',,') + 2, length(csm) - instr(csm, ',,') - 1) stud_id from (select univ_id, max(csa) csm from (select univ_id, to_char(round(avgm, 2)||',,'||s.stud_id) csa from student s, (select stud_id, avg(mark) avgm from exam_marks group by stud_id) a where s.stud_id = a.stud_id) group by univ_id) Решение, конечно, дубовое, но все-таки выдает верный результат. Хотя есть проблемы, связанные с тем, что максимальный средний балл могут иметь несколько студентов в университете (на кафедре), а в моем примере выводится только один из них, имеющий максимальный идентификатор (номер). З.Ы. К сожалению, переложить и проверить это решения для Access'а не могу в виду его (Access'а) хронического отсутствия и незнания. Но, думаю, ход моих мыслей тебе понятен.
__________________
Действовать надо тупо и это лучшее доказательство нашей чистоты и силы! |
|
|
|
|
# 9 | |
|
Guest
Сообщения: n/a
|
Цитата:
Код:
Max(Avg(Экзамен.Оценка) Теперь по первому примеру. в первом подзапросе Код:
select G.K kafedra, S.SNAME student, AVG(E.GRADE) avgrade from G join S on G.NG=S.GN join E on S.S=E.S group by G.K, S.SNAME в третьем подзапросе Код:
select G.K kafedra, AVG(E.GRADE) avgrade from G join S on G.NG=S.GN join E on S.S=E.S group by G.K Т.о. имея средний бал каждого студента и средний бал по каждой кафедре нельзя найти на каждой кафедре студента с наибольшим средним балом. А теперь почему запрос в котором вызывается третий подзапрос пытается найти кафедру с максимальным средним балом, я переделал запрос что бы Access его понял Код:
SELECT k.kafedra, k.student, k.avgrade FROM [SELECT Группа.Кафедра, Студент.Фамилия, Avg(Экзамен.Оценка) AS [Avg-Оценка] FROM (Группа INNER JOIN Студент ON Группа.[Номер группы]=Студент.[Номер группы]) INNER JOIN Экзамен ON Студент.Идентификатор=Экзамен.[Идентификатор студента] GROUP BY Группа.Кафедра, Студент.Фамилия ]. AS k WHERE (k.kafedra, k.avgrade) in ( select m.kafedra, MAX(m.avgrade) from ( SELECT Группа.Кафедра, Avg(Экзамен.Оценка) AS [Avg-Оценка] FROM (Группа INNER JOIN Студент ON Группа.[Номер группы]=Студент.[Номер группы]) INNER JOIN Экзамен ON Студент.Идентификатор=Экзамен.[Идентификатор студента] GROUP BY Группа.Кафедра) m group by m.kafedra ); Из подчиненного запроса, который не использует ключевое слово EXISTS в предложении FROM главного запроса, возвращается более одного поля. Укажите в инструкции SELECT подчиненного запроса возвращение только одного поля. (Ошибка 3306) по моему это ошибка вот тут Код:
MAX(m.avgrade) |
|
|
|
# 10 |
|
Junior Member
Регистрация: 15.05.2002
Сообщения: 168
![]() ![]() ![]() ![]() ![]() |
Вы совершенно правы, в том подзапросе закралась ошибочка, он должен быть таким же как и первый. Ведь идея заключается вот в чем, получаем множество студентов со средними значениями по кафедрам и получаем множество студентов с максимальными значениями по кафедрам, на основе первого запроса,. И из первого множества выбираем только те что входят во второе. Тем самым показывая 'злощастных' студентов.
В oracle это работает: Код:
SQL> select k.kafedra, k.student, k.avgrade 2 from ( 3 select G.K kafedra, S.SNAME student, AVG(E.GRADE) avgrade 4 from G join S on G.NG=S.GN join E on S.S=E.S 5 group by G.K, S.SNAME) k 6 where (k.kafedra, k.avgrade) in ( 7 select m.kafedra, MAX(m.avgrade) 8 from ( 9 select G.K kafedra, AVG(E.GRADE) avgrade 10 from G join S on G.NG=S.GN join E on S.S=E.S 11 group by G.K, S.SNAME) m 12 group by m.kafedra 13 ); KAFEDRA STUDENT AVGRADE -------------------- ---------- ---------- kat1 Petrov 7 kat2 Vasin 7 SQL> select G.K kafedra, S.SNAME student, AVG(E.GRADE) avgrade 2 from G join S on G.NG=S.GN join E on S.S=E.S 3 group by G.K, S.SNAME; KAFEDRA STUDENT AVGRADE -------------------- ---------- ---------- kat1 Ivanov 5.33333333 kat1 Petrov 7 kat1 Pupkin 5 kat1 Sidorov 4.83333333 kat2 Lenin 6.33333333 kat2 Mishin 6 kat2 Popov 5.66666667 kat2 Vasin 7 8 rows selected. SQL> select G.K kafedra, AVG(E.GRADE) avgrade 2 from G join S on G.NG=S.GN join E on S.S=E.S 3 group by G.K, S.SNAME; KAFEDRA AVGRADE -------------------- ---------- kat1 5.33333333 kat1 7 kat1 5 kat1 4.83333333 kat2 6.33333333 kat2 6 kat2 5.66666667 kat2 7 8 rows selected. SQL> select m.kafedra, MAX(m.avgrade) 2 from ( 3 select G.K kafedra, AVG(E.GRADE) avgrade 4 from G join S on G.NG=S.GN join E on S.S=E.S 5 group by G.K, S.SNAME) m 6 group by m.kafedra; KAFEDRA MAX(M.AVGRADE) -------------------- -------------- kat1 7 kat2 7
__________________
"Да, человек смертен, но это было бы еще полбеды. Плохо то, что он иногда внезапно смертен, вот в чем фокус!" Михаил Булгаков. Мастер и Маргарита Последний раз редактировалось Kiva; 06.05.2005 в 11:27. |
|
|
|
|
# 11 | |
|
Guest
Сообщения: n/a
|
Цитата:
. Но думаю что вот этот кусокКод:
max(csa) И еще не могу понять как работает вот это Код:
substr(csm, 1, instr(csm, ',,') - 1) |
|
|
|
# 12 |
|
Advanced Member
Регистрация: 15.09.2004
Адрес: Украина, Хмельницкий
Сообщения: 403
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
Вот наваял тебе решение в Аксессе (Аксеса2003). Там три запроса, конечный результат выдает запрос под названием Result.
__________________
The man in black fled across the desert, and the Gunslinger followed. (c) S.King |
|
|