Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.12.09;
Скачать: CL | DM;

Вниз

Уведомление   Найти похожие ветки 

 
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;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.022 c
15-1194848225
Slider007
2007-11-12 09:17
2007.12.09
С днем рождения ! 12 ноября 2007 понедельник


15-1194355266
Kemuri
2007-11-06 16:21
2007.12.09
Различия между процедурой и функцией


2-1194597990
031178
2007-11-09 11:46
2007.12.09
Трафик


2-1194962162
Malik
2007-11-13 16:56
2007.12.09
ShellAPI парадокс и ничего более??


2-1195104416
АндрейК
2007-11-15 08:26
2007.12.09
Пробелом выделить нужные строки в DBGrid