![]() |
Модераторы: skyboy |
![]() ![]() ![]() |
|
Akella |
|
|||
![]() Творец ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 18485 Регистрация: 14.5.2003 Где: Корусант Репутация: нет Всего: 329 |
Я не знаю, как можно было бы правильно озаглавить тему, мозгов не хватило.
Есть таблица объявлений. Основное, что нам понадобится здесь - это 6 полей (boolean) на каждый день с понедельника по субботу, т.е. на какой день нужно публиковать объявление. для наглядности (весь DDL наверное ненужно представлять здесь?): ![]() Вот запрос, который подсчитывает количество объявлений в таблице для конкретного пользователя, а вернее сумму денег, которую он должен внести в кассу:
В таблице VID хранятся стили и цены объявлений Таблицы VID и ADS связаны по полю ADS.vid (ADS.vid = VID.id) но здесь не учитываются дни недели: ![]() Получается, что одно объявление может быть опубликовано 6 раз, если пользователь отметил в таблице все дни недели. Ну или 2 раза, если отмечены только Вт и Чт, даже если в таблице 1 запись (1-но объявление) Выполнять 6 раз запрос отдельно или c UNION для каждого дня недели? Может есть другой ит правильный путь? |
|||
|
||||
Zloxa |
|
|||
![]() Чо? ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3473 Регистрация: 12.9.2008 Репутация: 53 Всего: 161 |
Мог не правильно понять, но мне кажется что вместо:
достаточно написать
Соответственно если 0 = нет, 1 - да. Если не так, то привести к нулю и единице. -------------------- Достоверно известно, что 89% людей доверяют статистике взятой с потолка ![]() |
|||
|
||||
Akella |
|
|||
![]() Творец ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 18485 Регистрация: 14.5.2003 Где: Корусант Репутация: нет Всего: 329 |
ок, проверим
Добавлено через 2 минуты и 50 секунд да, ты неправильно понял в таблице VID нет дней недели, в таблице VID живет цена объявления Таблица VID ![]() Добавлено через 13 минут и 31 секунду создал такой запрос
посмотрим, что получится ![]() нужно всё теперь ручками перепроверить, но идея богатая ![]() ![]() |
|||
|
||||
Zloxa |
|
|||
![]() Чо? ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3473 Регистрация: 12.9.2008 Репутация: 53 Всего: 161 |
Тогда в твоем первом запросе не правильно использовать v.id в count. Он не вернет 0, если ads не сможет подтянуться, получишь еденички там, где должен был быть 0 ![]() -------------------- Достоверно известно, что 89% людей доверяют статистике взятой с потолка ![]() |
|||
|
||||
Akella |
|
|||
![]() Творец ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 18485 Регистрация: 14.5.2003 Где: Корусант Репутация: нет Всего: 329 |
Работет! (С)
Добавлено через 48 секунд Zloxa, ![]() |
|||
|
||||
Zloxa |
|
|||
![]() Чо? ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3473 Регистрация: 12.9.2008 Репутация: 53 Всего: 161 |
Наврал я. Предикаты Выродят left join в inner -------------------- Достоверно известно, что 89% людей доверяют статистике взятой с потолка ![]() |
|||
|
||||
Akella |
|
|||
![]() Творец ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 18485 Регистрация: 14.5.2003 Где: Корусант Репутация: нет Всего: 329 |
не совсем понял ход твоих мыслей
|
|||
|
||||
Zloxa |
|
||||||||
![]() Чо? ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3473 Регистрация: 12.9.2008 Репутация: 53 Всего: 161 |
Смысл в том, что если ты в секции where фильтруешь по четким критериям вроде равенства, неравенства, без оговорок на null'абельность подсоединяемого внешним соединением набора данных, то outer join вырождается в inner.. т.е. запросы
и
Эквивалентны, потому что критерий b.somve_val = 'hello' отфильтрует те данные из таблицы а, которым не нашлось сопоставления в таблице b. Чтобы этого не происходило и внешнее соединиение не вырождалось во внутреннее, надо либо переносить критерии отбора в критерии объединения, либо допускать не определенность в предикатах фильтра т.е. либо
либо [code=sql]
Добавлено через 4 минуты и 35 секунд Я это все к тому, что, при этих условиях, твой count(v.id) никогда не вернет нуль, и по этой причине его замена на count(a.vid), что я находил ранее более правильным, ничего не даст. Добавлено через 5 минут и 15 секунд Но использование left join в подобных случаях, это обфускация в чистом виде ![]() -------------------- Достоверно известно, что 89% людей доверяют статистике взятой с потолка ![]() |
||||||||
|
|||||||||
Akella |
|
|||
![]() Творец ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 18485 Регистрация: 14.5.2003 Где: Корусант Репутация: нет Всего: 329 |
||||
|
||||
Akella |
|
|||
![]() Творец ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 18485 Регистрация: 14.5.2003 Где: Корусант Репутация: нет Всего: 329 |
Усложняем запрос.
Оказалось, что нужно вычислять сумму отдельно платных и бесплатных объявлений, опираясь на поле paid. Как-то так
|
|||
|
||||
Akella |
|
||||
![]() Творец ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 18485 Регистрация: 14.5.2003 Где: Корусант Репутация: нет Всего: 329 |
Не могу понять, почему этот запрос возвращает 10 и 1, хотя по идее должен вернуть 7 и 4
![]() а если "выкусить" из него часть запроса
то получается уже не 10, а 7 ![]() я понимаю, что всё дело в поле paid, т.к. именно на одну запись разница (где a.vt = 1 a.ch =1 a.sb = 1, получается 3) |
||||
|
|||||
Akella |
|
|||
![]() Творец ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 18485 Регистрация: 14.5.2003 Где: Корусант Репутация: нет Всего: 329 |
дело в том, что в указанных в where полях, отсутствуют записи с NULL-значениями |
|||
|
||||
Akella |
|
|||
![]() Творец ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 18485 Регистрация: 14.5.2003 Где: Корусант Репутация: нет Всего: 329 |
на другом форуме подсказали IF
|
|||
|
||||
Zloxa |
|
|||
![]() Чо? ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3473 Регистрация: 12.9.2008 Репутация: 53 Всего: 161 |
Я понял в чем подвох. Дело не в case/if
здесь в результате a.paid примет ЛЮБОЕ значение из тех, которые присутствуют в группе. Так же, как и v.price. Но, в отличии от v.price, который для группы будет всегда одинаков, т.к. группировка происходит по v.id, потому этот "любой" всегда будет одинаков, a.paid в пределах группы может принимать различные значения, и "любой", в зависимости от времени года и сочетания звезд на небе, может принимать непредсказеумые значения. Все нормальные движки запрещают подобную мешанину аггрегируемых и не аггрегируемых данных. MySQL - исключение. Правильное решение - перенести case внутрь sum. Как это сделано в примере с if. Это сообщение отредактировал(а) Zloxa - 31.5.2012, 11:51 -------------------- Достоверно известно, что 89% людей доверяют статистике взятой с потолка ![]() |
|||
|
||||
Akella |
|
||||
![]() Творец ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 18485 Регистрация: 14.5.2003 Где: Корусант Репутация: нет Всего: 329 |
Добавлено через 58 секунд
да пытался я, только запутался со скобками, в итоге забросил case Добавлено через 5 минут и 26 секунд А теперь мне надо ещё осложнить запрос ![]() проблема заключается вот в чем: для тех записей, у которых a.pn = 1 нужно взять не v.price, а v.price_d ![]() |
||||
|
|||||
![]() ![]() ![]() |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Составление SQL-запросов | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |