-
Привет всем. Есть запрос к PARADOX с LoookUp полями SUMDOG, LEVEL из другого TQuery (*) где поле LEVEL является вычисляемым DataSet.FieldByName('LEVEL').AsInteger:= DataSet.RecNo; В запросе (*) есть суммы и обратная сортировка по ним. Поле LEVEL - позиция (чтото вроде лидера по продажам). Так вот поле SUMDOG (из селекта) нормально отображается в TDBGrid-e, поле LEVEL = 0, а не номер отсортированной записи. Почему так происходит?
-
Да, забыл вот, TDBGrid привязан к запросу в котором созданы лукап поля, а не запросу (*).
-
> [0] BUM (02.07.08 10:45) > Почему так происходит?
Потому, что запрос идет к таблицам в БД, а не к твоему датасету, который и знает твое вычисленное значение.
-
> Потому, что запрос идет к таблицам в БД, а не к твоему датасету, > который и знает твое вычисленное значение.
Я вообщето считал что в лукап поле подставляется значение из сформированного датасета найденое в нем по ID записи, провернулся - нашол - подставилось. Зачам же опять лезть на сервер когда набор уже сформирован и поле (хоть и вычисляемое) в датасете есть? И почему 0 а не пусто, как например это происходит для записей не найденых в лукапном датасете? Т. е. в гриде отображается как LEVEL = 0, Null, Null, 0, 0, 0, Null...
-
> [3] BUM (02.07.08 11:22)
Я кажется невнимательно твой первый пост почитал. Т.е. получается, что твой первый (главный) запрос ссылается на детальный, в котором есть вычисляемое поле. Так? И это поле ты пытаешься вывести? Что-то мне сомнительно, что такое возможно.
-
> Так? И это поле ты пытаешься вывести?
Иммено так. В чем затык тут. И почему это сомнительно возможно. В гриде запрос (*) отображается как надо, а в котором подставили нули и пустоты. ?
-
> [5] BUM (02.07.08 11:40)
Видимо (не копал, потому не утверждаю) событие поиска значения при лукапе не вызывает пересчета калк полей в справочном датасете.
-
Межет можно как-то еще вывести номер позиции суммы в результирующем наборе в зависимости от лукапной суммы? Что-то второй день не соображу как ;( PS: Params.Text:= IntToStr(Result.RecNo); в событии GetCellParams Grida не подходит т. к. есть сортировка по столбцам в OnTitleClick. Надо именно в наборе иметь это поле.
-
> при лукапе не вызывает пересчета калк полей в справочном > датасете
Т. е. при открытии справочного датасета не происходит вычисление Calk поля?
-
Может ктото делал такую вещь как, например, выделить красным цветом 3 самых больших величины в TDBGride? Мне цветом не надо, просто указать номер в списке в зависимости от величины.
-
>BUM
Вычисляемое поле вполне м.б. отображаемым через лукапное. Если тебе интересно, в чем дело, приводи все необходимые подробности.
-
> Если тебе интересно, в чем дело, приводи все необходимые > подробности.
Ну я вроде всё опИсал выше.. Есть запрос (1): ID менеджера, Кол-во звонков, Кол-во замеров Есть запрос (2): ID менеджера, Sum(договор) As SUMDOG Order By SUMDOG Desc, а также калк поле LEVEL: DataSet.FieldByName('LEVEL').AsInteger:= DataSet.RecNo; для расчета места по продажам В (1) запрос вставил лукап поля из (2) SUMDOG и LEVEL по ID менеджера. Потом к этой связке через TDataSetProvider цепляется TClientDataSet (это для возможности сортировки (индексации) по полям) на который вешается TDBGridEh, в котором по нажатию на титл меняется индекс. В итоге получаю 0, Null, Null, 0, 0, 0, Null... пусто там где небыло найдено соответствие ID менеджера. Вобщем так.
-
Всё это происходит до какого-либо нажатия на титл и индексации просто в LEVEL 0 и пусто.
-
Как организованы лукап поля?
> В итоге получаю ...
Где?
-
Что значит
> Как организованы лукап поля?
не совсем понял. Может это имелось ввиду: В запросе (1) FieldKind = fkLookup FieldName = LEVEL KeyField = IDMANAGER LookUpDataSet = запрос (2) LookUpKeyField = IDMANAGER LookResultField = LEVEL
> Где?
В гриде, точнее в CDS который привязан к запросу (2)
-
> В гриде, точнее в CDS который привязан к запросу (2)
К запросу (1) конечно
-
> пусто там где небыло найдено соответствие ID менеджера.
А что же ещё м.б. показано, если не найдено соответствие?
ЗЫ Общее впечатление, что изобретается некий велик с квадратными колесами...:)
-
> некий велик с квадратными колесами...:)
Велик наверное называется "невозможность использовать во From подзапросы в LocalSQL" Может запросом можно както: Упрощенно Есть допустим таблица звонков T1: IDMANAGER, CALLSCOUNT, DATE и таблица договоров T2: IDMANAGER, DOGSUM, DATE, STAGE Таблица звонков ведущая Нужно выбрать из таблицы T1 звонки между датами и присоединить к ней таблицу T2 по IDMANAGER чтобы В T2 DATE тоже была между этими датами и состояние STAGE было > 50. Пока без подзапроса не получается. При попытке использовать T1 Left Join T2 On ... Where T1. =.. And T2. =.. выбирается только записи удовлетворяющие всем условиям, а при T1 Left Join T2 On ... And T2. = ... Where T1. =.. вообще виснет. Поэтому разбил на несколько запросов с группировками и присоединил к ведущему. Считается быстро и правильно. Тока как быть с порядковыми номерами.
-
> Нужно выбрать из таблицы T1 звонки между датами и присоединить > к ней таблицу T2 по IDMANAGER чтобы В T2 DATE тоже была > между этими датами и состояние STAGE было > 50.
> При попытке использовать T1 Left Join T2 On ... Where T1. > =.. And T2. =.. выбирается только записи удовлетворяющие > всем условиям
А разве д.б. как-то по-другому?
-
> [17] BUM (02.07.08 16:27)
select * from t1,t2 where t1.IDMANAGER=t2.IDMANAGER and t2.STAGE >50 and t1.date between :d1 and :d2 and t2.date between :d1 and :d2 order by по вкусу
Смущает имя поля DATE. + возможно придется сделать 4 параметра, а не 2 - я не помню как это интерпретируется в локальном скуле.
-
> Смущает имя поля DATE. > + возможно придется сделать 4 параметра, а не 2 - я не помню > как это интерпретируется в локальном скуле.
T1."DATE" - это для примера, про параметры знаю.
> select * from t1,t2 > where t1.IDMANAGER=t2.IDMANAGER > and t2.STAGE >50 > and t1.date between :d1 and :d2 > and t2.date between :d1 and :d2 > order by по вкусу
Договоров может не быть а звонки есть. Мне нужны Суммы по всем звонкам и по всем договорам где были звонки по данному IDMANAGER + условие отбора по договорам STAGE + Between между датами там и там.
-
Здесь очень хорошо подошли LookUp поля и разброс запросов по разным TQuery (что удобно для разбора) но тут возникла необходимость указывать рейтинг по договорам. Если бы это был T-SQL написал бы через вложеные запросы.
-
> [21] BUM (02.07.08 16:58) > указывать рейтинг по договорам
Я все-таки как-то не особо понял про эти рейтинги. Есть звонки менеджеру, у него же есть какие то договоры. Как они между собой связаны, кроме того что принадлежат одному менеджеру? Если есть 1 звонок и 100 договоров - что нужно вывести?
-
> Sergey13 © (02.07.08 17:06) [22]
Звонков больше чем договоров т.к. звонок может не перейти в заключение договора. Утрировано менеджер ведет конкретного заказчика от звонка до выполненого договора. Так что они связаны только по менеджеру. Вообще это статистика работы менеджера за период.
-
> [23] BUM (02.07.08 17:17)
Да я не про это. Есть 2 звонка и 2 договора. Если выводить запрос на соединение этих таблиц по связи t1.IDMANAGER=t2.IDMANAGER то получим 4 записи 1 1 1 2 2 1 2 2 Вопрос. Зачем это надо и что это дает?
-
> Sergey13 © (03.07.08 08:36) [24]
Речь вот о чем. Таблица договоров и таблица звонков никак на связаны между собой. Просто в них есть ссылки на таблицу менеджеров. Ну и даты конечно присутствуют. Вот надо сделать статистику по менеджеру скока было звонков за период и скока договоров, их суммы. Т. е. если звонков 2 и договоров 2 то должно получится ФИО Звонков Договоров Сумма(руб) Пупкин 2 2 1000 Я это сделал через отдельные запросы с IDMANAGER в селекте и привязал к первому запросу по звонкам как к ведущему, с выводом в лукап поля через связку по IDMANAGER. Вот встал вопрос как вывести в отдельное поле рейтинг 1, 2, 3 по менеджеру в зависимости от суммы по договорам.
-
> [25] BUM (03.07.08 09:19) > Таблица договоров и таблица звонков никак на связаны между собой. Тогда для НОРМАЛЬНОЙ статистики, ИМХО, нужно или 2 (два) нормальных независимых отчета
или для
> ФИО Звонков Договоров Сумма(руб) > Пупкин 2 2 1000
это можно сделать примерно так
Select FIO, (select count() from t1 where....) as CallCount,(select count() from t2 where....) as DogCount from ManagerTable
-
> Select FIO, (select count() from t1 where....) as CallCount, > (select count() from t2 where....) as DogCount > from ManagerTable
Щас проверю. Спасибо. Надеюсь такая конструкция в локалскул поддерживается
-
Дело в том что в статистике таких полей 7 и справочных запросов 4 штуки со своими условиями. Поэтому было удобно делать через лукап поля.
-
> Select FIO, (select count() from t1 where....) as CallCount, > (select count() from t2 where....) as DogCount > from ManagerTable
Тут такая хрень что из (select count() from t1 where....) у меня подставляется 4 поля. Такое можно былобы сделать через From (select count() from t1 where....) T1, Попробую конечно через Select FIO, (select count() from t1 where....) as CallCount, (select Sum() from t1 where....) As SUMDOG, .... и т. д. но чтото мне подсказывает что будут тормоза. А задача всегото идентифицировать 1 2 и 3 место по продажам
-
> Попробую конечно через > Select FIO, (select count() from t1 where....) as CallCount, > (select Sum() from t1 where....) As SUMDOG, ....
Точнее конечно Select T1.FIO, count(T1.*) as CallCount, (select Count(*) from t2 where....) As SUMDOG, , (select Sum() from t2 where....) As COUNTDOG, ... Помойму нето чтото. Надо проверить
-
> [28] BUM (03.07.08 09:32) > Дело в том что в статистике таких полей 7
Дело в том, что в вопросе желательно описывать РЕАЛЬНЫЕ условия. Иначе иногда получается, что все решают ДРУГУЮ задачу.
Есть таблица менеджеров? Если все поля, кроме ФИО агрегаты, то наверное должен прокатить и такой вариант
Select FIO, count(T1.*),count(T2.*),sum(t2.DOGSUM) from ManagerTable MT,T1,T2 where MT.IDMANAGER = t1.IDMANAGER and MT.IDMANAGER = t2.IDMANAGER and T2.date .....
-
> Sergey13 © (03.07.08 10:00) [31] Спасибо что стока со мной возились. Попробую конечно: > Select FIO, count(T1.*),count(T2.*),sum(t2.DOGSUM) > from ManagerTable MT,T1,T2 > where > MT.IDMANAGER = t1.IDMANAGER > and MT.IDMANAGER = t2.IDMANAGER > and T2.date .....
Насчет > в вопросе желательно описывать РЕАЛЬНЫЕ условия. Иначе иногда > получается, что все решают ДРУГУЮ задачу.
Думаю что задачу поставил корректно, но в реале это выглядит неприглядно не думаю чтобы комуто захотелось вникать: Ведущий запрос:
SELECT
W.NUMBER As IDMANAGER, W.FIO,
Count(*) As CZVONK, Count(DC.ZAMER) As CZAMER
FROM
DAYCALLS DC Left Join WORKERS W
On W.NUMBER = DC.WORKER
Where
DC.WORKER > 0 And
DC."DATE" Between :DATEBEG And :DATEEND And
W.CATEGORY = :CATEGORY
GROUP BY W.NUMBER, W.FIO
ORDER BY CZVONK DESC
Справочные:
Select
O.ZAMERMANAGER As IDMANAGER,
Count(O.NUMBER) As CDOG, Sum(O.SUMMA) As SUMMADOG,
Sum(WINDOWSAREA) As WAREA, Sum(DOORSAREA) As DAREA
From
ORDERS O, WORKERS W
Where
O.STAGE >= 50 And
O.ZAMERMANAGER = W.NUMBER And
O.CONTRACTDATE Between :DATEBEG And :DATEEND
Group By O.ZAMERMANAGER
Order By SUMMADOG Desc
SELECT
C.WORKER As IDMANAGER, Count(C.ZAMER) As CZAMTODOG
FROM
ORDERS O, DAYCALLS C, WORKERS W
WHERE
O.NUMBER = C.ZAKAZ And
C.WORKER = W.NUMBER And
O.STAGE >= 50 And
C."DATE" Between :DATEBEG And :DATEEND
Group By C.WORKER
SELECT
O.ZAMERMANAGER As IDMANAGER,
Count(*) As COTKOS, Sum(O.SUMMAR) As SUMMAOTK
FROM SHTUKDOG O, WORKERS W
WHERE
O.STAGE >= 50 And
O.ZAMERMANAGER = W.NUMBER And
O.CONTRACTDATE Between :DATEBEG And :DATEEND
Group By O.ZAMERMANAGER
SELECT
IDMANAGER, Sum(TIMESTOPFAKT - TIMESTARTFAKT)*24 As WORKTIME
FROM
SCHMANAG
WHERE
WORKDATE Between :DATEBEG And :DATEEND
Group By IDMANAGER
+ куча вычисляемых полей в ведущем по лукапам. Понимаю что-то можно было бы объединить, но разбил специально по задачам для простоты чтения и правки. Просто если помните вопрос изначально стоял в другом - почему при создании лукапного поля на основе вычисляемого LEVEL в нем отображаются 0. Но всё равно Sergey13 огромное спасибо! за терпение.
-
> [32] BUM (03.07.08 10:19) > Думаю что задачу поставил корректно
А я так не думаю. В твоих запросах я насчитал штук 5 таблиц, а вопросе фигурировало 2 запроса и вопрос о лукапе к калк полю. А как теперь выясняется нужен сводный отчет по манагерам, о которых было известно только то, что у них где-то есть ИД.
-
> А как теперь выясняется нужен сводный отчет по манагерам, > о которых было известно только то, что у них где-то есть > ИД.
Да вообщем-то бог с ним с отчетом по манагерам. Какая разница скока там запросов и таблиц и полей. 1 2 или 3 4 5 Интересовало именно
> вопрос о лукапе к калк полю
100 к 1 что будь там 2 запроса вед. и справ., как я представил, результат будет тотже.
-
> [34] BUM (03.07.08 10:53) > Какая разница
Разница в том, что возможно все решается 1 запросом. Но ты решаешь проблему лукапа, потому что решил делать так как решил.
-
> Sergey13 © (03.07.08 11:17) [35]
Ок. Буду пытаться решать через объединение первых двух запросов. Спасибо. Тему можно закрывать. PS: Что делать, раз в наследство досталась такая структура базы данных, да еще реализованная на Paradox-e со всем богатством возможностей LocalSQL. Хотя зря я, дело давно минувших дней, не ругаться же едучи на паровозе что нельзя обогнать А310.
-
> [35] Sergey13 © (03.07.08 11:17) > > [34] BUM (03.07.08 10:53) > > Какая разница > > Разница в том, что возможно все решается 1 запросом
Увы. Запрос из [26] Sergey13 © (03.07.08 09:27) хорош для IB, "кривоват" для МS SQL и совершенно не работает в Local.
Запрос из [31] Sergey13 © (03.07.08 10:00) тоже нехорош из-за "перемножения" T1 и T2, а стало быть неверных значений агрегатов.
самым лучшим со всех точег зрения быдо бы SELECT ... FROM ManagerTable m LEFT JOIN (...запрос расчета первой характеристики...) q1 ON m.Id = q1.Id LEFT JOIN (...запрос расчета второй характеристики...) q2 ON m.Id = q2.Id ...
Подзапросы q1, q2 - когда ни без параметров - лекго решаются с помощью Local View
Но так как характеристики считаются за периоды, т.е. по выборкам, а не по всей таблице, то возможны 2 рещения: 1) динамическое создание Local View и запросов их использующих 2) отбор записей во временные "агрегатные" таблицы, соответствующие по структуре запросам q1, q2 а затем использованеие их в запросе
При многопользовательском режиме разумно иметь "серверную" и "локальную" БД и использовать механизм гетерогенных запросов.
-
Кстати, если обойтись без Calculated в датасете полей,то можно обойтись и механизмом lookup-полей. Только все числа в агрегирующих запросах qn должны считаться SQL-ем.
-
> самым лучшим со всех точег зрения быдо бы > SELECT ... > FROM > ManagerTable m > LEFT JOIN (...запрос расчета первой характеристики... > ) q1 ON m.Id = q1.Id > LEFT JOIN (...запрос расчета второй характеристики... > ) q2 ON m.Id = q2.Id
Так бы и делал для T-SQL Подзапросы в From не работают в LocalSQL.
> 2) отбор записей во временные "агрегатные" таблицы, соответствующие > по структуре запросам q1, q2 а затем использованеие их в > запросе > > При многопользовательском режиме разумно иметь "серверную" > и "локальную" БД и использовать механизм гетерогенных запросов. >
Работа в терминале через VPN в одной директории на сервере. Не то
|