Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > Составление SQL-запросов > SQL-запрос |
Автор: kvadrokub 18.10.2010, 08:10 |
Всем доброго времени суток. На экзамене по БД попался такой вопрос с написанием SQL-запроса: Имеется таблица: ++++++++++++++++++++++++++++ | id | Номер команды | Результат | ++++++++++++++++++++++++++++ | 1 | 10 | 1000 | | 2 | 12 | 1100 | | 3 | 10 | 500 | | 4 | 11 | 700 | | ... | ... | ... | ++++++++++++++++++++++++++++ Найти номер команды, которая больше всего раз встречается в таблице. Вот примерно так выглядит условие. Помогите, пожалуйста. |
Автор: Akina 18.10.2010, 08:24 | ||
|
Автор: kvadrokub 18.10.2010, 08:26 |
top 1 - это, получается, одно самое большое значение? |
Автор: Akina 18.10.2010, 08:30 |
При указанной сортировке - да. Есссно это диалектозависимо - например в MySQL это будет LIMIT 1. |
Автор: kvadrokub 18.10.2010, 08:33 | ||
Тогда немного конкретизирую задачу. Написать без top 1, а с помощью подзапросов. Также, чтобы не было диалектозависимо, а было на чистом SQL. |
Автор: Данкинг 18.10.2010, 09:09 |
Это как так, интересно? Тебе Akina пример запроса привёл, а далее говоришь преподу, что частный случай зависит от конкретной СУБД. ![]() |
Автор: kvadrokub 18.10.2010, 09:14 | ||
Нужно как раз-таки написать так, чтобы запрос работал на любой СУБД одинаково и не нужно было ничего менять, т.е. на голом ANSI SQL. Ну, например, только с использованием max и count. |
Автор: Zloxa 18.10.2010, 09:42 | ||||
SQL92
Вернет ВСЕ команды, повторяющиеся наиболшьшее количество раз. может статься, что этот запрос вполне соответствует и SQL86 SQL2003
Вернет любую одну команду, повторяющуюся наибольшее количество раз Если нужно чтобы были выведены все команды, повторяющиеся наибольшее количество раз, row_number заменить на dence_rank Добавлено @ 09:46 следует отметить что SQL2003 держут отнюдь не все движки. Ровно как и SQL92 |
Автор: Akina 18.10.2010, 10:01 | ||
|
Автор: kvadrokub 18.10.2010, 10:02 |
Вау, супер! ![]() ![]() А у меня первоначальный вариант был примерно такой: SELECT TEAM FROM TABLE, (SELECT TEAM, COUNT(TEAM) AS CNT FROM TABLE GROUP BY TEAM) A WHERE TABLE.TEAM = A.TEAM AND (SELECT MAX(CNT) FROM A) = и вот тут ступор ![]() |
Автор: Zloxa 18.10.2010, 10:05 |
предикат вернет истину для каждой строки. |
Автор: kvadrokub 18.10.2010, 10:36 |
Кстати говоря, никто из вас не умеет правильно писать запросы. ![]() ![]() |
Автор: Zloxa 18.10.2010, 10:39 |
ты не мог бы намекнуть менее прозрачно? |
Автор: kvadrokub 18.10.2010, 10:41 | ||
Я про этот запрос: select command from table group by commmand having count(*) = (select max(count(*)) from table group by command) |
Автор: Zloxa 18.10.2010, 10:42 |
Иииииии? |
Автор: Akina 18.10.2010, 10:43 | ||
![]() |
Автор: kvadrokub 18.10.2010, 10:44 |
http://www.sql-tutorial.ru/ru/book_group_by_clause.html |
Автор: Zloxa 18.10.2010, 10:45 |
И все же... Иииииии? |
Автор: kvadrokub 18.10.2010, 10:46 | ||
Ну создай таблицу, запусти и попробуй. |
Автор: Zloxa 18.10.2010, 10:49 |
Мне то это зачем? Я знаю где ошибся, но к сути вопроса это отношения не имеет. Хотя да, ты прав. Я ступил. Надо было тебе посоветовать взять букрварь по SQL и почитать его. |
Автор: kvadrokub 18.10.2010, 10:56 |
Вот это твой запрос: select command from table group by commmand having count(*) = (select max(count(*)) from table group by command) Буду разбирать по косточкам. Возьму для начала вложенный подзапрос: select max(count(*)) from table group by command Во-первых, нельзя писать max(count(*)). Во-вторых, правильно будет выглядеть так: select command, count() или max() - одно из двух from table group by command , т.е. ошибка в написании GROUP BY. Его нельзя использовать так, как ты там писал. Третяя ошибка вглавном запросе, там также в первой строке нужно использовать агрегатную функцию, иначе опять-таки GROUP BY выдаст ошибку. Ну и в четвёртых, исходя из всех этих ошибок весь запрос неверен. Проверял на MySQL, знаю по Oracle. Ну и команда по-английски team, а не command, хотя это не важно, в принципе. Я же говорю, создайте и попробуйте сами, если не верите мне. |
Автор: Frees 18.10.2010, 11:07 |
kvadrokub, а вопрос то у тебя какой, или ты возмущен что тебе дали не вылизанный запрос? Ты сам думай как делать направление тебе дали, включи голову и не бухти.. |
Автор: kvadrokub 18.10.2010, 11:43 |
С тем, что не обязательно использовать агрегатную функцию с GROUP BY соглашусь, но вот MAX(COUNT(*)), по крайней мере в MySQL (Oracle недавно снёс и не могу проверить), нельзя писать: http://file.qip.ru/photo/_CxZwRKZ/sql.html? |
Автор: Zloxa 18.10.2010, 12:00 | ||
оберни в подзапрос
|
Автор: kvadrokub 18.10.2010, 12:06 |
Уже. Спасибо за помощь, извини за нападки. ![]() |
Автор: Zloxa 18.10.2010, 12:31 |
И тебе спасибо, узнал что аггрегат от аггрегата - экзотика. MS,PG,Access так тоже не могут. В оракле эта фишка http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/functions001.htm#sthref962. Может ктонить про FB сказать? |
Автор: Frees 18.10.2010, 12:40 |
в FB 2.0 агрегат от агрегата - нельзя |
Автор: Akina 18.10.2010, 13:05 |
Zloxa, экотика - это агрегатная функция без group by. Вернее, либо group by присутствует, пусть и в неявной форме (поля группировки определяются перечнем полей в остальных частях запроса), либо на выходе должна получаться 1 запись вне зависимости от входного набора данных (и 0 записей - если входной набор пуст), но не больше. А вот если идёт агрегатка от агрегатки... при наличии групбай перечень полей группировки явно никак не подходит либо к внутренней, либо к внешней агрегатке, а при отсутствии внешний групбай к набору из максимум одной записи бессмыслен. |
Автор: Zloxa 18.10.2010, 14:40 | ||||||||
ХМ. имхо это не экзотика, а вполне себе общепринятая практика. без этого бы очень плохо жилось.
Есть такое правило, что при использовании аггрегата без группировки всегда возвращается одна и только одна строка. Именно по этому агрегацию без группировки нельзя представлять как аггрегацию с неявной группировкой по чему бы там ни было. Это обособленный случай. Аггрегация с группировкой, по пустому набору, вернет пустой набор. Аггрегация без группировки, по пустому набору, вернет одну запись.
MS и PG ведут себя так же
При вложенной аггрегации, внутренний аггрегат всегда применяется к группам, а внешний - к результату внутреннего, подразумевая отсутствие группировки. Оракля не разрешает вложенные аггрегаты без груп бая. И той неоднозначности, о которой ты говоришь - нет.
|