Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 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
2-1194516434
Andy BitOff (ppc)
2007-11-08 13:07
2007.12.09
Разница между датами


2-1195204449
031178
2007-11-16 12:14
2007.12.09
SendMail


1-1190089977
APXi
2007-09-18 08:32
2007.12.09
Странная работа TreeView


2-1194979500
Б. Гейтс
2007-11-13 21:45
2007.12.09
Над контролом ли мышь? (API only)


15-1194354763
авыф
2007-11-06 16:12
2007.12.09
Запись формы.





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский