Форум: "Начинающим";
Текущий архив: 2007.12.09;
Скачать: [xml.tar.bz2];
ВнизУведомление Найти похожие ветки
← →
delphino (2007-11-12 07:56) [0]Есть две таблицы (клиенты и договора), связанные в отношении 1 ко многим (одному клиенту соответствует много договоров, т.е.срок договора заканчивается вносится другой договор и т.д.). Хочется, чтобы отслеживались срок окончания договоров и выдавалось уведомление за месяц до окончания.
Я сделала SQL выборку договоров таких, чтобы срок окончания попадал в интервал от Now-30 до Now. Проблема в том, что если пользователь вносит для какого-то клиента новый договор, то прежний договор продолжает попадать в этот интервал и программа соответственно продолжает выдавать уведомление об истекающем сроке договора.
← →
Sergey13 © (2007-11-12 08:40) [1]Ошибка в программе.
← →
Anatoly Podgoretsky © (2007-11-12 09:01) [2]Ну ты же сама хотела, что бы все договора в этом интервале, вот и получи или переделывай запросы/структуру
← →
delphino (2007-11-12 09:19) [3]
> Ошибка в программе.
Да ошибки нет. У меня просто даже мыслей нет как можно решить поставленную задачу. Была правда мысль делать отдельно выборку только текущих договоров и уже их проверять, но по-моему это не лучший выход, к тому это занимает очень много времени. Вот я и спрашиваю как можно это по-другому решить..
← →
Sergey13 © (2007-11-12 09:24) [4]> [3] delphino (12.11.07 09:19)
> Да ошибки нет.
Нет ошибки синтаксиса. Но раз результат работы программы неправильный - там ошибка. Например ты берешь просто все договора, а надо брать только последние договора клиента.
← →
Anatoly Podgoretsky © (2007-11-12 09:40) [5]Это тоже не верно, надо брать только те договора, у которых нет продления, у клиента много договоров, у части срок уже закончился, у части еще нет, осталось менее месяца и нет продление. Проще всего ввести понятие продление договора или замена новым договором, тогда запрос будет простой Date < and not new contract
В данном поле просто писань новый номер, если заключается новый договор или тот же самый если продляется
← →
delphino (2007-11-12 09:50) [6]
> надо брать только последние договора клиента
А как их брать? Брать каждого клиента и проверять все договора? Трудоемкая задача...
> Проще всего ввести понятие продление договора или замена
> новым договором, тогда запрос будет простой Date < and not
> new contract
Это как? Ввести еще одно поле в таблицу договоров? Вряд ли это возможно, т.к.пользоватеди с программой уже работают
← →
Sergey13 © (2007-11-12 09:55) [7]> [6] delphino (12.11.07 09:50)
> А как их брать?
Учить SQL и брать.
← →
Anatoly Podgoretsky © (2007-11-12 09:58) [8]
> А как их брать? Брать каждого клиента и проверять все договора?
> Трудоемкая задача...
Я думаю что никак, но ты и не привела примера данных.
Например новый договор имеет новый номер или старый, если старый то возможно через группирование и функцию MAX, если новый то без связи никак.
> Это как? Ввести еще одно поле в таблицу договоров? Вряд
> ли это возможно, т.к.пользоватеди с программой уже работают
Недостаточно данных для ответа.
← →
ЮЮ © (2007-11-12 09:59) [9]> Я сделала SQL выборку договоров таких, чтобы срок окончания
> попадал в интервал от Now-30 до Now. Проблема в том,
Чтобы решать проблему, надо хотя бы запрос видеть.
← →
mufan (2007-11-12 10:08) [10]
> срок договора заканчивается вносится другой договор
т.е. получается в определенный момент времени одному клиенту соответствует только один договор (текущий), хотя этому же клиенту принадлежит несколько договоров в таблице с договорами (истекшие договора ведь не удаляются???)???
Если так, то я предположу, что раз в таблице есть дата истечения, то есть и дата подписания???
← →
delphino (2007-11-12 10:14) [11]Структура таблицы договора (paradox) такая:
1.CO_Code - ключ
2.CO_Number - номер договора (тип - Alpha)
3.CO_Year - год договора (Integer)
4.C_Code - ключ к таблице клиенты
5.CO_Begin - дата начала действия
6.CO_End - дата окончания действия
SQL -запрос: select C.C_Name, CO.CO_Begin, CO.CO_End from clients C, contracts CO where CO.C_Code=C.C_Code
И далее фильтрую Query:
Query1.Filter := Format("CO_End < %s", [QuotedStr(FormatDateTime("dd.mm.yyyy ", Now))])+" and "+Format("CO_End > %s", [QuotedStr(FormatDateTime("dd.mm.yyyy ", Now-30))]);
Хотя по идее это не очень правильно вместо Now-30 должно быть CO_End-30 (для того чтобы уведомление выдавалось за месяц до окончания).
← →
delphino (2007-11-12 10:15) [12]
> т.е. получается в определенный момент времени одному клиенту
> соответствует только один договор (текущий), хотя этому
> же клиенту принадлежит несколько договоров в таблице с договорами
> (истекшие договора ведь не удаляются???)???
>
> Если так, то я предположу, что раз в таблице есть дата истечения,
> то есть и дата подписания???
Абсолютно верно! Причем номера нового и предыдущего договора не совпадают
← →
Anatoly Podgoretsky © (2007-11-12 10:25) [13]> delphino (12.11.2007 10:15:12) [12]
Значит нужно дополнительное поле - номер нового договара, иначе никак не реализуешь задачу, да и удобнее работать с подобной структурой, можно просмотреть цепочки договоров.
← →
ЮЮ © (2007-11-12 10:38) [14]
Select C_Code, Max(CO_End) FROM contracts GROUP BY C_Code HAVING Max(CO_End) + 30 < :ControlDate
Для любителей фильтровать: HAVING можно опустить и фильтровать на клиенте.
Поля из clients слелать Lookup-ными на клиенте.
Для желающих получить поля из clients и contracts в ожном запросе оформить local view, например
Select C_Code, Max(CO_End) MaxCoEnd FROM contracts GROUP BY C_Code
и тогда запрос примет видselect
C.C_Name, CO.CO_Begin, CO.CO_End
from
"MaxCoEnds.sql" lastCo
JOIN contracts CO On (CO.C_Code=lastCo.C_Code) And (CO.CO_End = lastCo.MaxCoEnd)
JOIN clients C On C.C_Code=lastCo.C_Code
where
lastCo.C_Code ...
Для любителей фильтровать: WHERE можно опустить и фильтровать на клиенте.
← →
delphino (2007-11-13 05:10) [15]ЮЮ спасибо огромное ты как всегда выручил!
Только один вопрос, как вместо ControlDate подставить значение Now?
Пробовала QuotedStr(FormatDateTime("dd.mm.yyyy ", Now)) - выдает ошибку Capability not supported
← →
ЮЮ © (2007-11-13 06:01) [16]> Только один вопрос, как вместо ControlDate подставить значение
> Now?
Не надо вместо, надо вместе. Для float, string и datetime полей всяко лучше использовать параметры.
В тексте запроса оставить параметр :ControlDate, а перед открытием запроса проставлять параметру значениеQuery.Params[0].asDateTime := Date(); // Now() ещё и время содердит, а оно тебе надо ???
> Capability not supported
Какой вариант выбрала? Как окончательно выглядит запрос?
← →
delphino (2007-11-13 06:58) [17]окончательно запрос выглядит так:
select C.C_Name, Max(CO.CO_End) MaxCoEnd
from contracts CO, clients C where C.C_Code=Co.C_Code
GROUP BY C.C_Name Having (Max(CO.CO_End) >="12.12.2007") and (Max(CO.CO_End) -30<="12.12.2007")
Только вместо "12.12.2007" нужно подставить текущую дату.
← →
ЮЮ © (2007-11-13 08:43) [18]>Только вместо "12.12.2007" нужно подставить текущую дату.
А в таком, к конкретными константами, варианте работает? Capability not supported только при формировнии строки? Тогда участок кода, формирующий запрос - в студию - ошибка может быть только там.
З.Ы. Клиентов - полных тезок нет и быть не может? Если могут быть, не мешает C.C_Code в группировку добавить
← →
Anatoly Podgoretsky © (2007-11-13 09:24) [19]> delphino (13.11.2007 06:58:17) [17]
Во первых тебе Now совсем не нужен, получишь только ошибки выполнения запроса, а нужно DATE
А в запросе примени параметры, но твой запрос очень странный он даст результат только если есть дата строго равная 12.12.2007 00:00:00,000, допустим такая дата у тебя есть, но зачем де тогда дважды вычислят >= и <=, когда можно один раз и оператор =
← →
ЮЮ © (2007-11-13 09:38) [20]> [19] Anatoly Podgoretsky © (13.11.07 09:24)
Этот запрос соответствует Max(CO.CO_End) BETWEEN "12.12.2007" AND "12.12.2007" + 30, а это 31 вариант вощможных значений.
Capability not supported возможно из-за использования переменых сразу трех типов в выражении
Max(CO.CO_End) -30<="12.12.2007"
Проще Date() + 30 "вычислить" на клиенте, а в запросе упростить до
Max(CO.CO_End) BETWEEN "xx.yy.zzzz" AND "aa.bb.cccc"
← →
Anatoly Podgoretsky © (2007-11-13 09:49) [21]Увидел -30
Вычислить так IncMonth(Date) и соотношение меньше или равно заменить на меньше.
← →
delphino (2007-11-13 10:15) [22]
> А в таком, к конкретными константами, варианте работает?
Да если дату явно задавать - все работает.
> Проще Date() + 30 "вычислить" на клиенте, а в запросе упростить
> до
> Max(CO.CO_End) BETWEEN "xx.yy.zzzz" AND "aa.bb.cccc"
Да нужна всего одна дата - текущая, я пробовала получить ее из DateTimePicker.Date - ошибка
Invalide use keyword
Почему не воспринимается обкавыченная дата, если ее вводить неявно, я думала в синтаксисе проблема?
← →
ЮЮ © (2007-11-13 10:24) [23]> [22] delphino (13.11.07 10:15)
> [18] ЮЮ © (13.11.07 08:43)
> Тогда участок кода, формирующий запрос - в студию - ошибка
> может быть только там.
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2007.12.09;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.038 c