![]() |
|
Модераторы: skyboy |
![]()
|
|
| JEEN |
|
||||||||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 88 Регистрация: 8.3.2008 Репутация: 1 Всего: 1 |
Язык SQL, какой конкретно - не сказано, но личном мне ближе MySQL.
Есть 3 таблицы: KN – книги, KL – клиенты, VD – выдача книг как-то так
я сделал так, но не уверен:
здесь, возможно, union надо использовать?
буду благодарен за любую помощь. Это сообщение отредактировал(а) JEEN - 10.3.2012, 19:54 |
||||||||||
|
|||||||||||
| JEEN |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 88 Регистрация: 8.3.2008 Репутация: 1 Всего: 1 |
неужели никто не знает хотя бы какие функции здесь используются?
|
|||
|
||||
| Zloxa |
|
||||
|
Чо? ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3473 Регистрация: 12.9.2008 Репутация: 53 Всего: 161 |
1) Не выдержано условие
Ваш запрос вернет значение 0 вместо неопределенности, если клиенту книги не выдавались 2) 2.1) Не реализован в MySQL 2.2) Не точно соответствует указанному в постановке задачи "Список клиентов" Пальцем в небо? Второе задание аналогично первому, если вы первую задачу решили самостоятельно(или хотя бы поняли принцип ее решения), совершенно не понятно ваше недоумевание над способом решения второй. 1)Не задавайте вопросы из домашних заданий 2)Для помощи лентяям существует центр помощи 3)Если вы не лентяй, попробуйте опубликовать свои версии решений. Оценим, подскажем, обсудим, но не решим за вас. Это сообщение отредактировал(а) Zloxa - 11.3.2012, 09:28 -------------------- Достоверно известно, что 89% людей доверяют статистике взятой с потолка |
||||
|
|||||
| JEEN |
|
||||||||||||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 88 Регистрация: 8.3.2008 Репутация: 1 Всего: 1 |
Я сам написал первую задачу, только нашел функцию FULL OUTER JOIN по запросу "внешнее соединение sql", почему то думал, что вернет именно null, а не ноль. А вот со второй не могу разобраться, потому что не знаю как из null сделать 0 и наоборот. вот некоторые задачи, которые уже решил Список книг авторов «Иванов», «Петров» и «Андреев», упорядоченный сначала по убыванию по авторам, затем по возрастанию по названиям;
Список клиентов, фамилии которых заканчиваются на «ов»;
Список кодов книг, которые выдавались (без повторов);
Список клиентов, которым выдавались книги с указанием количества выдач;
последний запрос работает, только без указания количества выдач. Пытаюсь сделать так:
но всем книгам присваивается по одной выдаче. Почему так? Список книг, которые не выдавались;
Это сообщение отредактировал(а) JEEN - 11.3.2012, 09:50 |
||||||||||||||
|
|||||||||||||||
| Zloxa |
|
|||
|
Чо? ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3473 Регистрация: 12.9.2008 Репутация: 53 Всего: 161 |
В результате соединения, в случае отсутствия совпадения по критериям соединения, для соединяемых столбцов действительно вернется null. Но только вот количество у вас подсчитывается функцией count, которая не определенного значения не возвращает. Гуглите еще. Внешние соединения бывают трех типов. Впрочем, полное внешнее соединение в этом сулчае, при условии согласованности данных таки решает поставленную задачу. Но его применение все равно для решения задачи в этой постановке - не оправданно. vd.sr может принимать значение null. Фильтруясь по этому критерию вы можете упустить некоторые "выдачи" к тому же фильтроваться вам не надо, вам все равно навдо вывести клиентов, которым ничего не выдавалось. смотрите по чем группируетесь. Это сообщение отредактировал(а) Zloxa - 11.3.2012, 10:01 -------------------- Достоверно известно, что 89% людей доверяют статистике взятой с потолка |
|||
|
||||
| JEEN |
|
||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 88 Регистрация: 8.3.2008 Репутация: 1 Всего: 1 |
да это уже просто так поставил, до этого группировал по VD.KK (код клиента), все равно каждому по одному ставит. Группировал по книгам, это не удовлетворяет услвию задачи, но хоть не единицы стояли. вот кстати таблица "выдача" ![]()
я видимо вчера не так прочитал задачу, думал "с указанием срока выдачи". Спасибо за замечание Это сообщение отредактировал(а) JEEN - 11.3.2012, 10:05 |
||||
|
|||||
| Zloxa |
|
|||
|
Чо? ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3473 Регистрация: 12.9.2008 Репутация: 53 Всего: 161 |
Ну а теперь смотрите на свои данные, почему должно быть иначе. Только клиенту 3 была выдача более одного раза, но ее вы зачем то отфильтровали по "sr is not null" Ну и опять же, группироватсья по vd.kk - не правильно. Те клиенты, которым не было выдано ни одной книги, попадут в одну группу. -------------------- Достоверно известно, что 89% людей доверяют статистике взятой с потолка |
|||
|
||||
| JEEN |
|
||||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 88 Регистрация: 8.3.2008 Репутация: 1 Всего: 1 |
точно... невнимательность. Сделал так, теперь все как надо выводит
нам же они вообще не нужны. В условии "клиенты, которым выдавались книги". Или я не так понял опять? |
||||||
|
|||||||
| Zloxa |
|
|||
|
Чо? ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3473 Регистрация: 12.9.2008 Репутация: 53 Всего: 161 |
Где у нас это условие? Я исхожу из условия в топикстарте:
По этому условию нам таки нужны в результате клиенты, которым книги не выдавались. Если же нам не нужны эти клиенты, делать внешнее соединение, а потом, с помощью условия " WHERE VD.KK IS NOT NULL" сводить результат к внутреннему - тоже нелепость. Это сообщение отредактировал(а) Zloxa - 11.3.2012, 10:22 -------------------- Достоверно известно, что 89% людей доверяют статистике взятой с потолка |
|||
|
||||
| JEEN |
|
||||||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 88 Регистрация: 8.3.2008 Репутация: 1 Всего: 1 |
делаю так:
все точно так же как и в предыдущем случае, но возникает ошибка. Разве cnt нельзя использовать в запросе? цифру 1 я использовал вместо 5 временно, потом поправлю. Добавлено через 1 минуту и 29 секунд
мы немного о разных задачах говорим. я вот про эту:
|
||||||||
|
|||||||||
| Zloxa |
|
|||
|
Чо? ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3473 Регистрация: 12.9.2008 Репутация: 53 Всего: 161 |
Да, нельзя. Условия where отрабатывают до выполнения группировки, а потому не могут опираться на значения, полученные в ее результате rtfm having Добавлено @ 10:36 Внешнее соединение здесь не уместно. Благодаря условию в where оно деградирует до внутреннего(я об этом уже упоминал), фильтрация по VD.SR постановкой задачи не обусловлена. Добавлено через 8 минут и 18 секунд Вобще, по этой самой причине, чтобы все говорили об одном и том же, обычно на один вопрос открыают один топик. Это сообщение отредактировал(а) Zloxa - 11.3.2012, 10:39 -------------------- Достоверно известно, что 89% людей доверяют статистике взятой с потолка |
|||
|
||||
| JEEN |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 88 Регистрация: 8.3.2008 Репутация: 1 Всего: 1 |
Zloxa, огромное спасибо за помощь. Сейчас дошел до сложных задач, попытаюсь еще раз сам сделать, может выйдет что.
Список клиентов, бравших книги более 5 раз;
|
|||
|
||||
| Zloxa |
|
|||
|
Чо? ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3473 Регистрация: 12.9.2008 Репутация: 53 Всего: 161 |
Замечания все те же
1) эквивалентно внутреннему соединению, внешнее соединение - не уместно 2) При использовании внешнего соединения, в одну группу попадут все клиенты, для которых не было выдач. Вообще запрос работать будет. Но написан он стилистически криво. -------------------- Достоверно известно, что 89% людей доверяют статистике взятой с потолка |
|||
|
||||
| JEEN |
|
||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 88 Регистрация: 8.3.2008 Репутация: 1 Всего: 1 |
сейчас напишу что узнал, потом попробую разобраться с замечаниями.
в MySQL, как я понял, нет полного внешнего объединения их заменяет левое и правое внешнее объединение (left join, right join), собственно их я и использовал, поэтому запрос для задачи:
будет выглядеть примерно так.
если бы не "значение этого поля должно быть не определено" выходит, что надо использовать не count, а что-то другое? |
||||
|
|||||
| Zloxa |
|
|||
|
Чо? ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3473 Регистрация: 12.9.2008 Репутация: 53 Всего: 161 |
Для решения конкретно этой задачи полного внешнего не требуется, а левое оно тоже вполне себе внешнее.
Да, нелепое какое-то условие. Такое ощущение, что оно добавлено преподом от какой то другой задачи. Чтобы выполнит это условие, я бы использовал выражение case, но выглядело бы это как-то кастыльно. -------------------- Достоверно известно, что 89% людей доверяют статистике взятой с потолка |
|||
|
||||
| JEEN |
|
||||||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 88 Регистрация: 8.3.2008 Репутация: 1 Всего: 1 |
я не понимал разницу между всеми join'ами, поэтому везде исползовал left join. Сейчас прочитал еще раз внимательно, дошло. Запрос еще проще выглядит. фильтрация по VD.SR случайно попала, я просто скопировал со старого решения. на счет группировки аналогично, мне казалось я все испробовал, только VD.KK работало. Сейчас сгруппировал по KL.KK, получилось. В общем, задача:
старое решение
новое решение
|
||||||||
|
|||||||||
| JEEN |
|
||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 88 Регистрация: 8.3.2008 Репутация: 1 Всего: 1 |
только функция avg не выдает 0, если книгу не брали.. |
||||
|
|||||
| Zloxa |
|
||||||||
|
Чо? ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3473 Регистрация: 12.9.2008 Репутация: 53 Всего: 161 |
Я именно так и понял, потому и был так настойчив Чисто чтоб закрепить - я как-то рисовал картинку. Мне кажется достаточно доходчиво должно бы быть. Осталось одно только замечание. Это будет работать только на MySQL. Стандарт SQL запрещает в списке полей select использовать поля, не перечисленные в group by без применения к ним аггрегатных функций. MySQL единственный из известных мне движков не реализует этого запрета. Разработчики отписываются, мол это для оптимизации, и ограничивают область использования этой фичи в документации. Соответственно, чтобы оторваться от диалекта MySQL вам осталось лишь выдержать это ограничение заменив
на
Добавлено через 4 минуты и 39 секунд
Тут, кстати, тонкий момент. VD.SR может принимать неопределенное значение, и если оно используется, функция avg его не будет использовать при расчете. avg([1,null]) = 1, в то время, как avg([1,0]) = 0.5. Но в постановке задачи этот ньюанс не огооврен, думаю, можно забить(но держать в уме, я бы такой вопрос поднял бы на защите) -------------------- Достоверно известно, что 89% людей доверяют статистике взятой с потолка |
||||||||
|
|||||||||
| JEEN |
|
||||||||||||||||||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 88 Регистрация: 8.3.2008 Репутация: 1 Всего: 1 |
хорошие картинки, как-то давно натыкался на подобное, только там круги были. Тогда не сохранил и забыл где видел, а вашу картинку сохранил на комп)
я так понял здесь без разницы что max, что min использовать? лишь бы была какая-то функция?
получилось) только у преподавателя даже нет возможности спросить/проконсультироваться. На дистанционке учусь. вот еще пару запросов сделал, может есть какие-то замечания..
остались 2 задачи, которые никак не получаются.
сделал вот так:
но здесь мешает HAVING COUNT, потому что он считает, что должно быть больше 10 записей, которые брались больше чем на 30 дней. Т.е. сначала выполняется WHERE, отсеивает часть, потом по оставшимся уже проходится HAVING COUNT. А надо как-то, чтобы они вместе работали, например WHERE VD.SR > 30 and count(VD.K) > 10, но тогда GROUP BY мешает.
эм.. тут я даже не представляю как должен вывод выглядеть, речь о 2х разных списках идет. Что-то такого что ли: - Иванов, Петров, Сидоров - Горе от ума (3) - Иванов, Козлов - Евгений Онегин (2) и т.д. разве такой список можно сделать только одним запросом? в общем, я бы, наверное, прошелся по списку книг, у каждой проверял кто ее брал, если ее брали > 1 человека, то выводить ее.. |
||||||||||||||||||||
|
|||||||||||||||||||||
| Zloxa |
|
|||
|
Чо? ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3473 Регистрация: 12.9.2008 Репутация: 53 Всего: 161 |
тут не знаю. Я пишу на оракле. Оракл не умеет делать жойн для делита. not in или not exists с моей точки зрения выглядило бы как более универсальное решение. C not in - ньюанс: применимо только к not nullable набору данных. Здесь возможна неоднозначность трактовки задачи 1) Книга бралась более 10 раз и всякий раз на срок не менее 30 дней, тогда ваш подход - правильный 2) Книга бралась более 10 раз на общий срок не менее 30 дней, тогда суммируем сроки и отсекаем в havind Мне кажется первый вариант самый близкий к исходной задаче, и вы соврешенно правильно его реализовали. Хотя второй вариант тоже похож на правду. В принципе - то же самое. Группироваться по паре (id_клиент,id_книга) -------------------- Достоверно известно, что 89% людей доверяют статистике взятой с потолка |
|||
|
||||
| JEEN |
|
||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 88 Регистрация: 8.3.2008 Репутация: 1 Всего: 1 |
у меня серьезные проблемы с пониманием условий %) перечитал 200 раз и до меня дошло, что "Список клиентов, бравших одну и ту же книгу" эту фразу я не так понимаю, думал что нужно найти общие интересы клиентов)) в общем сделал вот так
все работает как надо. Zloxa, спасибо вам огромное. Без вас бы не разобрался. Поставил бы плюсик к каждому посту, но пока 100 сообщений не набрал, нельзя плюсики ставить. |
||||
|
|||||
| Zloxa |
|
|||
|
Чо? ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3473 Регистрация: 12.9.2008 Репутация: 53 Всего: 161 |
Ну и тебе спасибо, что ты не лентяй, не ждал готовых решений, готов был разбираться и думать. Побольше бы таких начинающих. Это сообщение отредактировал(а) Zloxa - 11.3.2012, 14:20 -------------------- Достоверно известно, что 89% людей доверяют статистике взятой с потолка |
|||
|
||||
| Zloxa |
|
|||
|
Чо? ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3473 Регистрация: 12.9.2008 Репутация: 53 Всего: 161 |
Так то это тоже просто. Селфджойн:
получаем список общих интересов -------------------- Достоверно известно, что 89% людей доверяют статистике взятой с потолка |
|||
|
||||
![]()
|
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Составление SQL-запросов | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |