SQLinfo.ru - Все о MySQL

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 29.03.2010 21:02:44

Артём Н.
Активист
Зарегистрирован: 03.11.2009
Сообщений: 156

Не получается составить запрос

Имеется следующая таблица:

Код:

Период
использования
транспортного
средства:              Коэффициент  

3 месяца               0,4 
4 месяца               0,5 
5 месяцев             0,6
6 месяцев             0,7 
7 месяцев             0,8 
8 месяцев             0,9 
9 месяцев             0,95 
10 месяцев
и более                 1

В БД я представил её так:
ins_koefs_ks
а.) k PERIOD_USE - период использования ТС в месяцах.
б.) KS - значение коэффициента.

Мне нужно получить значение коэффициента, в зависимости от периода использования.

Для получения значения коэффициента, я пробовал следующий запрос:

select KS, if(@tmp = min(PERIOD_USE) is NULL, max(PERIOD_USE), @tmp)
from ins_koefs_ks
where
:period <= PERIOD_USE

Всё бы хорошо, но при значении параметра period > 10, ничего не выбирается,
поэтому условие не работает и возвращает NULL.

Возможно ли сделать такую выборку одним запросом?


"И ни птица, ни ива слезы не прольет,
Если сгинет с земли человеческий род.
И весна, и весна встретит новый рассвет,
Не заметив, что нас уже нет..."

Неактивен

 

#2 29.03.2010 21:42:38

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Не получается составить запрос

SELECT coeff FROM tablename WHERE period < :period ORDER BY period DESC LIMIT 1;

Неактивен

 

#3 29.03.2010 22:04:27

Артём Н.
Активист
Зарегистрирован: 03.11.2009
Сообщений: 156

Re: Не получается составить запрос

o.O И всё? Спасибо. :-)


"И ни птица, ни ива слезы не прольет,
Если сгинет с земли человеческий род.
И весна, и весна встретит новый рассвет,
Не заметив, что нас уже нет..."

Неактивен

 

#4 29.03.2010 22:15:36

Артём Н.
Активист
Зарегистрирован: 03.11.2009
Сообщений: 156

Re: Не получается составить запрос

Не то немного... Если период меньше, чем 3, то ничего не вернёт... :-(


"И ни птица, ни ива слезы не прольет,
Если сгинет с земли человеческий род.
И весна, и весна встретит новый рассвет,
Не заметив, что нас уже нет..."

Неактивен

 

#5 29.03.2010 22:27:07

Артём Н.
Активист
Зарегистрирован: 03.11.2009
Сообщений: 156

Re: Не получается составить запрос

И, если, 3.5 месяца, например, он вернёт 3, а не 4...


"И ни птица, ни ива слезы не прольет,
Если сгинет с земли человеческий род.
И весна, и весна встретит новый рассвет,
Не заметив, что нас уже нет..."

Неактивен

 

#6 29.03.2010 23:57:44

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5847

Re: Не получается составить запрос

Артём Н. написал:

Не то немного... Если период меньше, чем 3, то ничего не вернёт... :-(

А в базе есть данные за период меньше, чем три месяца?

Артём Н. написал:

И, если, 3.5 месяца, например, он вернёт 3, а не 4...(

Если вы подразумеваете, что при вводе периода за 3.5 месяца вы хотите получить данные за 4 месяца, то используйте period <= round(PERIOD_USE)
А лучше проводите обработку на клиенте до формирования запроса, чтобы PERIOD_USE имел не дробный вид, а округленный в нужную вам сторону.

Неактивен

 

#7 30.03.2010 00:44:16

Артём Н.
Активист
Зарегистрирован: 03.11.2009
Сообщений: 156

Re: Не получается составить запрос

А в базе есть данные за период меньше, чем три месяца?

Это "период сезонного использования". Например, ТС используется 3 месяца в году или менее.
К тому же, это только пример. Там сходных запросов несколько.

А лучше проводите обработку на клиенте до формирования запроса, чтобы PERIOD_USE имел не дробный вид, а округленный в нужную вам сторону.

Это, конечно, возможно... Но я, в принципе, не могу знать куда округлять...
Например, запрос для коэффициента мощности очень похожий.
К примеру, коэффициент один для многих ТС с двигателями, мощность, которых свыше 50, но менее 70 л.с. включительно.
В идеале, жёстко зашивать границы в клиент не следует, поскольку, теоретически они могут поменяться. А round() использовать тут не получится... :-(

Отредактированно Артём Н. (30.03.2010 00:46:03)


"И ни птица, ни ива слезы не прольет,
Если сгинет с земли человеческий род.
И весна, и весна встретит новый рассвет,
Не заметив, что нас уже нет..."

Неактивен

 

#8 30.03.2010 01:08:34

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5847

Re: Не получается составить запрос

Артём Н. написал:

А в базе есть данные за период меньше, чем три месяца?

Это "период сезонного использования". Например, ТС используется 3 месяца в году или менее.
К тому же, это только пример. Там сходных запросов несколько.

Не понял. Если ТС используется менее 3 месяцев, то как выглядит запись о ней в базе?

Неактивен

 

#9 30.03.2010 09:04:22

Артём Н.
Активист
Зарегистрирован: 03.11.2009
Сообщений: 156

Re: Не получается составить запрос

Еcть договор в своей таблице. В таблицу договоров заносятся значения коэффициентов.
Значения выбираются из справочника, но условия выборки расчитываются, исходя из условий договора. К примеру, есть дата начала страхования и дата окончания.
Разность - период. По периоду из справочника выбирается значение коэффициента, которое заносится в договор, используется при расчёте и т.д..


"И ни птица, ни ива слезы не прольет,
Если сгинет с земли человеческий род.
И весна, и весна встретит новый рассвет,
Не заметив, что нас уже нет..."

Неактивен

 

#10 30.03.2010 09:06:36

Артём Н.
Активист
Зарегистрирован: 03.11.2009
Сообщений: 156

Re: Не получается составить запрос

В первом случае, он ничего не выбирал, если значение превышает максимум в таблице.
В вашем запросе (в запросе от paulus) не выбирает, если значение меньше минимума.
Конечно, возможно два запроса использовать, но, наверное, имеется возможность сделать одним запросом?

Отредактированно Артём Н. (30.03.2010 10:06:40)


"И ни птица, ни ива слезы не прольет,
Если сгинет с земли человеческий род.
И весна, и весна встретит новый рассвет,
Не заметив, что нас уже нет..."

Неактивен

 

#11 30.03.2010 23:59:11

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Не получается составить запрос

Вы не ответили на главный вопрос — какой коэффициент должен быть,
если, например, 2 месяца? Если 0.4, то замените первую строку на
0 месяцев — 0.4. Это будет логично, а, раз логично, то и запрос работать
будет.

Неактивен

 

#12 31.03.2010 00:27:03

Артём Н.
Активист
Зарегистрирован: 03.11.2009
Сообщений: 156

Re: Не получается составить запрос

Да, если 2 месяца, то коэффициент должен быть 0,4. Если 11 месяцев, то 1.
Т.е., при меньшем/большем значениях периода - крайние коэффициенты.
Хм... В принципе, логично.
Но, что нехорошо. Ведь справочники возможно править. Если там будет стоять 0 в периоде использования... Неочевидно для пользователя.
Это первое.
Второе, и более важное - это то, что, в таком случае, при значении периода, к примеру, 3.5 он должен вернуть 0,5. Но он вернёт 0,4.

Конечно, двумя запросами сделать возможно. Но такое подозрение, что это возможно сделать как-то проще...

Отредактированно Артём Н. (31.03.2010 00:28:18)


"И ни птица, ни ива слезы не прольет,
Если сгинет с земли человеческий род.
И весна, и весна встретит новый рассвет,
Не заметив, что нас уже нет..."

Неактивен

 

#13 31.03.2010 00:35:10

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Не получается составить запрос

Попробуйте сделать из «маркетинговой» таблички «реальную». Если
в табличке написано, что 0.5 наступает *после* четырех месяцев, то
это именно так. А у Вас 0.5 наступает после *трех* месяцев.

Нужно делать так, как оно на самом деле есть, а не так, как лучше
надурить людей smile К слову сказать, если в маркетинговой табличке
написать словами «больше трех месяцев» — это будет понятно и от-
крыто. Возможно, больше клиентов привлечете простой честностью.
Ну и, когда люди честны с собой, у них и запросы пишутся проще wink

Неактивен

 

#14 31.03.2010 09:29:49

Артём Н.
Активист
Зарегистрирован: 03.11.2009
Сообщений: 156

Re: Не получается составить запрос

paulus написал:

Попробуйте сделать из «маркетинговой» таблички «реальную». Если
в табличке написано, что 0.5 наступает *после* четырех месяцев, то
это именно так. А у Вас 0.5 наступает после *трех* месяцев.

Уф, это я погорячился, наверное. %-)

Нужно делать так, как оно на самом деле есть, а не так, как лучше
надурить людей :)

Так коэффициенты в законе определены. Тут я просто, похоже, ошибся.
Спрошу ещё...
Хм... Но идея хорошая. ;-)

К слову сказать, если в маркетинговой табличке
написать словами «больше трех месяцев» — это будет понятно и от-
крыто. Возможно, больше клиентов привлечете простой честностью.
Ну и, когда люди честны с собой, у них и запросы пишутся проще ;)

Да эту табличку будет видеть только администратор, и то - редко. :-)
Когда меняются коэффициенты и нужно изменить их в справочнике. Это нечасто бывает.
Администратор меняет их через интерфейс, естественно, а не через запрос UPDATE в клиенте mysql. :-)
Представьте лёгкое удивление, когда вместо ожидаемых двух месяцев там будет стоять ноль...
Плюс ещё, охота сделать, чтобы число периодов тоже возможно было менять.
Зачем на практике - не знаю. Ради универсальности.

P.S.: Спасибо, что заметили ошибку с коэффициентами. Буду ещё перепроверять.
Может, где ещё напортачил. :-\


"И ни птица, ни ива слезы не прольет,
Если сгинет с земли человеческий род.
И весна, и весна встретит новый рассвет,
Не заметив, что нас уже нет..."

Неактивен

 

#15 31.03.2010 09:37:31

Артём Н.
Активист
Зарегистрирован: 03.11.2009
Сообщений: 156

Re: Не получается составить запрос

Поэтому, хочется просто из таблиц в БД коэффициенты скопировать, чтобы на клиенте не мудрить...


"И ни птица, ни ива слезы не прольет,
Если сгинет с земли человеческий род.
И весна, и весна встретит новый рассвет,
Не заметив, что нас уже нет..."

Неактивен

 

#16 01.04.2010 11:18:50

Артём Н.
Активист
Зарегистрирован: 03.11.2009
Сообщений: 156

Re: Не получается составить запрос

Хм... Нет, я не ошибся. Действительно, если 3.5 месяца, то коэффициент уже 0.5.
Не знаю так/не так, но как мне сказали, так я и делаю.
Так что запрос не проходит. Ничего в голову не идёт, да и запарился уже порядком...
Может, всё-таки, возможно одним запросом сделать?


"И ни птица, ни ива слезы не прольет,
Если сгинет с земли человеческий род.
И весна, и весна встретит новый рассвет,
Не заметив, что нас уже нет..."

Неактивен

 

#17 01.04.2010 16:43:10

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Не получается составить запрос

Напишите на бумажке преобразования из маркетинговой таблички в ту, по
которой можно что-то посчитать, потом запрограммируйте их и используйте,
когда нужно будет менять маркетинговую табличку.

Очень жаль, что Вам не нравится идея честности sad

Неактивен

 

#18 01.04.2010 22:24:57

Артём Н.
Активист
Зарегистрирован: 03.11.2009
Сообщений: 156

Re: Не получается составить запрос

Очень жаль, что Вам не нравится идея честности sad

Идея хорошая, но меня тут не спрашивают. :-) По идее, если ТС страхуется на период более 3-х месяцев, то считается, что оно страхуется на 4 месяца. Потому и коэффициент такой берётся. Вы меня слегка смутили, я посмотрел закон.
Не нашёл где об этом говорится. Наверное, смотрел плохо. Но делать-то мне, по-любому, придётся, как говорят.

paulus написал:

Напишите на бумажке преобразования из маркетинговой таблички в ту, по
которой можно что-то посчитать, потом запрограммируйте их и используйте,
когда нужно будет менять маркетинговую табличку.

Вот и вопрос. А без этого возможно сделать?


"И ни птица, ни ива слезы не прольет,
Если сгинет с земли человеческий род.
И весна, и весна встретит новый рассвет,
Не заметив, что нас уже нет..."

Неактивен

 

#19 02.04.2010 15:32:45

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Не получается составить запрос

Компьютеры работают по тому алгоритму, которому их научили. Вы можете
научить их врать, но каждое правило вранья надо описывать отдельно. Ну
и в MySQL не предусмотрено варианта быстрого вранья, поэтому прийдется
описывать через IF. Или сделать так, как я сказал раньше, — описать все
вранье в одном модуле, сделать честную табличку, а с честными данными
уже работать быстро smile

Неактивен

 

#20 02.04.2010 22:33:39

Артём Н.
Активист
Зарегистрирован: 03.11.2009
Сообщений: 156

Re: Не получается составить запрос

Компьютеры работают по тому алгоритму, которому их научили. Вы можете
научить их врать, но каждое правило вранья надо описывать отдельно. Ну
и в MySQL не предусмотрено варианта быстрого вранья, поэтому прийдется
описывать через IF. Или сделать так, как я сказал раньше, — описать все
вранье в одном модуле, сделать честную табличку, а с честными данными
уже работать быстро

Ну, если вы будете вдаваться в филосософию... С точки зрения диалектического материализма... %-)
Помните анекдот:

Как-то спросил  (после пятой) Чапаев у Фурманова о том что же такое философия.
Отвечает ему Фурманов:
- Ну как бы тебе объяснить, Василий Иваныч... Вот например: два мужика, один чистый, другой грязный, какой в баню пойдёт?
- Ну конечно грязный.
- Эээ, нет, Василий Иваныч.
Вот чему нас учит диалектика: грязный - он как есть по жизни грязный, ему в баню не хочется. А вот чистый - он так и будет к чистоте стремиться, значит он в баню пойдёт
- Надо же.. Вот люди-то умные какие. Так что же такое философия-то?
- Ну вот опять: два мужика, чистый и грязный, какой в баню пойдёт?
- Ну сам же сказал - чистый пойдёт.
- А вот логика нас учит: чистый - он и так чистый, зачем ему в баню? А вот грязному - мыться надо, он в баню пойдёт.
- Ох, и правда, наука, понимаешь. Ну, дальше что?
- Ну вот опять: два мужика, чистый и грязный, какой в баню пойдёт?
- Эх, совсем ты меня запутал. Хрен его знает!
- Вот, Василий Иваныч, вот это и есть - философия!

Даже геометрий совсем "честных" не существует, а вы говорите... ;-)
Что же касается меня. Для меня - это не враньё. Мне это надо сделать.
Поскольку:
1.) Есть люди, которые требуют именно это.
2.) Есть закон, который об этом говорит. Но утверждать я этого не могу, поскольку я не юрист, а сам лично не увидел. :-)

не предусмотрено варианта быстрого вранья, поэтому прийдется
описывать через IF.

IF возможно применять только в хранимых процедурах? :-(

Или сделать так, как я сказал раньше, — описать все
вранье в одном модуле, сделать честную табличку, а с честными данными
уже работать быстро

Вот представьте себе: штук двадцать справочников. Не так много. Но хватает.
Отображаются эти справочники в DBGrid'е. Одна форма на все.
Мне проще сделать через два запроса и функцию, чем для некоторых справочников делать отдельную обработку, а, тем более, интерфейс.
К тому же, времени нет. А лени много. :-)


"И ни птица, ни ива слезы не прольет,
Если сгинет с земли человеческий род.
И весна, и весна встретит новый рассвет,
Не заметив, что нас уже нет..."

Неактивен

 

#21 03.04.2010 00:51:31

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Не получается составить запрос

Ну, мой подход никак не конфликтует с тем, что Вы написали (а главное — с тем,
что надо сделать). Пусть у Вас есть табличка в DBGrid, в которой люди забивают
нелогичную информацию. После того, как они нажали «сохранить», вы делаете
хитрую подпольную операцию: сохраняете эти данные, как есть *и* переписыва-
ете честную табличку так, чтобы по ней можно было делать выборки. А людям,
которые не любят честное, ее не показываете. В результате достигаются следую-
щие цели:
  - Люди считают, что Вы пишете хорошие быстрые программы, даже если они
внаглую врут во входных данных;
  - Вам не надо врать себе, что данные хорошие — Вы для себя умеете отличать
хорошие данные от плохих;
  - Запросы строятся на базе хороших данных, а потому они простые и понятные.
Ну, и работают быстро, конечно wink

Неактивен

 

#22 03.04.2010 10:45:36

Артём Н.
Активист
Зарегистрирован: 03.11.2009
Сообщений: 156

Re: Не получается составить запрос

После того, как они нажали «сохранить», вы делаете
хитрую подпольную операцию: сохраняете эти данные, как есть *и* переписыва-
ете честную табличку так, чтобы по ней можно было делать выборки.

Теоретически, конечно, подход неплохой... Но как я буду делать "хитрую подпольную операцию"? smile
Во-первых, я не вижу очевидных путей для этого.
Во-вторых, мне сложно самому будет, "вручную" разбираться где какой период.
В-третьих, но самое важное, чтобы делать преобразование нужны ещё какие-то данные.
К примеру, если я поставлю 0, вместо 2-х, откуда я буду знать, что там период 2, а не 1, например? Опять же: надо где-то хранить... Менять структуру таблицы.
А хочется, чтобы таблица максимум соответствовала "бумажной".
В данном случае, это вполне возможно и оправданно (всего-то два столбца).

Я думаю, что лучше так:
1.) Получить коэф. для минимума (ну или максимума).
2.) Получить коэф.
3.) Если NULL, то использовать коэф., полученный в (1).

Причём, есть возможность сделать это на базе процедуры. На скорость выполнения, думаю, это не сильно повлияет.

Ну, в общем, я разобрался.
Спасибо. smile

P.S.:

- Люди считают, что Вы пишете хорошие быстрые программы, даже если они
внаглую врут во входных данных;

Ага, и кроют меня матом за то, что программа считает себя умнее их. :-\

Отредактированно Артём Н. (03.04.2010 10:47:05)


"И ни птица, ни ива слезы не прольет,
Если сгинет с земли человеческий род.
И весна, и весна встретит новый рассвет,
Не заметив, что нас уже нет..."

Неактивен

 

#23 03.04.2010 13:15:28

Артём Н.
Активист
Зарегистрирован: 03.11.2009
Сообщений: 156

Re: Не получается составить запрос

О, ееее!
Я попытался написать процедуру, но так и не въехал, как в процедуре вернуть результат запроса, чтобы использовать с IF, в дальнейшем, в той же процедуре. (Кстати, весьма интересно узнать, как?).

Но, тем не менее, я нашёл "механизм быстрого вранья". smile

Код:

select KS,
ifnull(min(if(PERIOD_USE >= :period), PERIOD_USE, NULL), max(PERIOD_USE))
from ins_koefs_ks;

Отредактированно Артём Н. (03.04.2010 13:16:49)


"И ни птица, ни ива слезы не прольет,
Если сгинет с земли человеческий род.
И весна, и весна встретит новый рассвет,
Не заметив, что нас уже нет..."

Неактивен

 

#24 03.04.2010 13:20:21

Артём Н.
Активист
Зарегистрирован: 03.11.2009
Сообщений: 156

Re: Не получается составить запрос

По крайней мере, возвращает нужный ID. :-\
Мда... Придётся подзапросом, всё равно, делать. sad
Примерно так:

Код:

select KS from ins_koefs_ks where PERIOD_USE = (select ifnull(min(if(PERIOD_USE >= :period), PERIOD_USE, NULL), max(PERIOD_USE))
from ins_koefs_ks);

Отредактированно Артём Н. (03.04.2010 13:20:56)


"И ни птица, ни ива слезы не прольет,
Если сгинет с земли человеческий род.
И весна, и весна встретит новый рассвет,
Не заметив, что нас уже нет..."

Неактивен

 

#25 03.04.2010 13:26:57

Артём Н.
Активист
Зарегистрирован: 03.11.2009
Сообщений: 156

Re: Не получается составить запрос

Плохо, что с JOIN Не работает:

Код:

select KS from ins_koefs_ks ik1 join ins_koefs_ks iks on
ik1.PERIOD_USE =
(ifnull(min(if(iks.PERIOD_USE >= :period), iks.PERIOD_USE, NULL), max(iks.PERIOD_USE)));

sad
Возможно ли такое для JOIN переделать?

Отредактированно Артём Н. (03.04.2010 13:27:46)


"И ни птица, ни ива слезы не прольет,
Если сгинет с земли человеческий род.
И весна, и весна встретит новый рассвет,
Не заметив, что нас уже нет..."

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson