Конференция "Базы" » LookUp поле по полю Calculate = 0 [D5, Paradox]
 
  • BUM (02.07.08 10:45) [0]
    Привет всем.
    Есть запрос к PARADOX с LoookUp полями SUMDOG, LEVEL из другого TQuery (*) где поле LEVEL является вычисляемым
    DataSet.FieldByName('LEVEL').AsInteger:= DataSet.RecNo;


    В запросе (*) есть суммы и обратная сортировка по ним. Поле LEVEL - позиция (чтото вроде лидера по продажам).
    Так вот поле SUMDOG (из селекта) нормально отображается в TDBGrid-e, поле LEVEL = 0, а не номер отсортированной записи.  Почему так происходит?
  • BUM (02.07.08 10:53) [1]
    Да, забыл вот, TDBGrid привязан к запросу в котором созданы лукап поля, а не запросу (*).
  • Sergey13 © (02.07.08 11:08) [2]
    > [0] BUM   (02.07.08 10:45)
    > Почему так происходит?

    Потому, что запрос идет к таблицам в БД, а не к твоему датасету, который и знает твое вычисленное значение.
  • BUM (02.07.08 11:22) [3]

    > Потому, что запрос идет к таблицам в БД, а не к твоему датасету,
    >  который и знает твое вычисленное значение.

    Я вообщето считал что в лукап поле подставляется значение из сформированного датасета найденое в нем по ID записи, провернулся - нашол - подставилось. Зачам же опять лезть на сервер когда набор уже сформирован и поле (хоть и вычисляемое) в датасете есть? И почему 0 а не пусто, как например это происходит для записей не найденых в лукапном датасете?
    Т. е. в гриде отображается как
    LEVEL = 0, Null, Null, 0, 0, 0, Null...
  • Sergey13 © (02.07.08 11:35) [4]
    > [3] BUM   (02.07.08 11:22)

    Я кажется невнимательно твой первый пост почитал.
    Т.е. получается, что твой первый (главный) запрос ссылается на детальный, в котором есть вычисляемое поле. Так? И это поле ты пытаешься вывести?
    Что-то мне сомнительно, что такое возможно.
  • BUM (02.07.08 11:40) [5]

    > Так? И это поле ты пытаешься вывести?

    Иммено так. В чем затык тут. И почему это сомнительно возможно. В гриде запрос (*) отображается как надо, а в котором подставили нули и пустоты.
    ?
  • Sergey13 © (02.07.08 12:05) [6]
    > [5] BUM   (02.07.08 11:40)

    Видимо (не копал, потому не утверждаю) событие поиска значения при лукапе не вызывает пересчета калк полей в справочном датасете.
  • BUM (02.07.08 12:08) [7]
    Межет можно как-то еще вывести номер позиции суммы в результирующем наборе в зависимости от лукапной суммы? Что-то второй день не соображу как ;(
    PS:
    Params.Text:= IntToStr(Result.RecNo);


    в событии GetCellParams Grida не подходит т. к. есть сортировка по столбцам в OnTitleClick. Надо именно в наборе иметь это поле.
  • BUM (02.07.08 12:15) [8]

    > при лукапе не вызывает пересчета калк полей в справочном
    > датасете

    Т. е. при открытии справочного датасета не происходит вычисление Calk поля?
  • BUM (02.07.08 12:21) [9]
    Может ктото делал такую вещь как, например,  выделить красным цветом 3 самых больших величины в TDBGride?
    Мне цветом не надо, просто указать номер в списке в зависимости от величины.
  • Johnmen © (02.07.08 13:11) [10]
    >BUM

    Вычисляемое поле вполне м.б. отображаемым через лукапное.
    Если тебе интересно, в чем дело, приводи все необходимые подробности.
  • BUM (02.07.08 13:43) [11]

    > Если тебе интересно, в чем дело, приводи все необходимые
    > подробности.

    Ну я вроде всё опИсал выше..
    Есть запрос (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 менеджера. Вобщем так.
  • BUM (02.07.08 13:49) [12]
    Всё это происходит до какого-либо нажатия на титл и индексации просто в LEVEL 0 и пусто.
  • Johnmen © (02.07.08 13:55) [13]
    Как организованы лукап поля?

    > В итоге получаю ...

    Где?
  • BUM (02.07.08 14:20) [14]
    Что значит

    > Как организованы лукап поля?

    не совсем понял. Может это имелось ввиду:
    В запросе (1)
    FieldKind = fkLookup
    FieldName = LEVEL
    KeyField = IDMANAGER
    LookUpDataSet = запрос (2)
    LookUpKeyField = IDMANAGER
    LookResultField = LEVEL

    > Где?

    В гриде, точнее в CDS который привязан к запросу (2)
  • BUM (02.07.08 14:25) [15]

    > В гриде, точнее в CDS который привязан к запросу (2)

    К запросу (1) конечно
  • Johnmen © (02.07.08 15:54) [16]

    > пусто там где небыло найдено соответствие ID менеджера.

    А что же ещё м.б. показано, если не найдено соответствие?

    ЗЫ
    Общее впечатление, что изобретается некий велик с квадратными колесами...:)
  • BUM (02.07.08 16:27) [17]

    > некий велик с квадратными колесами...:)

    Велик наверное называется "невозможность использовать во 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. =.. вообще виснет. Поэтому разбил на несколько запросов с группировками и присоединил к ведущему. Считается быстро и правильно. Тока как быть с порядковыми номерами.
  • Johnmen © (02.07.08 16:42) [18]

    > Нужно выбрать из таблицы T1 звонки между датами и присоединить
    > к ней таблицу T2 по IDMANAGER чтобы В T2 DATE тоже была
    > между этими датами и состояние STAGE было > 50.


    > При попытке использовать T1 Left Join T2 On ... Where T1.
    >  =.. And T2. =.. выбирается только записи удовлетворяющие
    > всем условиям

    А разве д.б. как-то по-другому?
  • Sergey13 © (02.07.08 16:42) [19]
    > [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 - я не помню как это интерпретируется в локальном скуле.
  • BUM (02.07.08 16:50) [20]

    > Смущает имя поля 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 между датами там и там.
  • BUM (02.07.08 16:58) [21]
    Здесь очень хорошо подошли LookUp поля и разброс запросов по разным TQuery (что удобно для разбора) но тут возникла необходимость указывать рейтинг по договорам. Если бы это был T-SQL написал бы через вложеные запросы.
  • Sergey13 © (02.07.08 17:06) [22]
    > [21] BUM   (02.07.08 16:58)
    > указывать рейтинг по договорам

    Я все-таки как-то не особо понял про эти рейтинги. Есть звонки менеджеру, у него же есть какие то договоры. Как они между собой связаны, кроме того что принадлежат одному менеджеру? Если есть 1 звонок и 100 договоров - что нужно вывести?
  • BUM (02.07.08 17:17) [23]

    > Sergey13 ©   (02.07.08 17:06) [22]

    Звонков больше чем договоров т.к. звонок может не перейти в заключение  договора. Утрировано менеджер ведет конкретного заказчика от звонка до выполненого договора. Так что они связаны только по менеджеру. Вообще это статистика работы менеджера за период.
  • Sergey13 © (03.07.08 08:36) [24]
    > [23] BUM   (02.07.08 17:17)

    Да я не про это.
    Есть 2 звонка и 2 договора. Если выводить запрос на соединение этих таблиц по связи t1.IDMANAGER=t2.IDMANAGER то получим 4 записи
    1 1
    1 2
    2 1
    2 2
    Вопрос. Зачем это надо и что это дает?
  • BUM (03.07.08 09:19) [25]

    > Sergey13 ©   (03.07.08 08:36) [24]

    Речь вот о чем. Таблица договоров и таблица звонков никак на связаны между собой. Просто в них есть ссылки на таблицу менеджеров. Ну и даты конечно присутствуют. Вот надо сделать статистику по менеджеру скока было звонков за период и скока договоров, их суммы. Т. е. если звонков 2 и договоров 2 то должно получится
    ФИО      Звонков  Договоров  Сумма(руб)
    Пупкин       2            2               1000
    Я это сделал через отдельные запросы с IDMANAGER  в селекте и привязал к первому запросу по звонкам как к ведущему, с выводом в лукап поля через связку по IDMANAGER. Вот встал вопрос как вывести в отдельное поле рейтинг 1, 2, 3 по менеджеру в зависимости от суммы по договорам.
  • Sergey13 © (03.07.08 09:27) [26]
    > [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
  • BUM (03.07.08 09:29) [27]

    > Select FIO, (select count() from t1 where....) as CallCount,
    > (select count() from t2 where....) as DogCount
    > from ManagerTable

    Щас проверю. Спасибо. Надеюсь такая конструкция в локалскул поддерживается
  • BUM (03.07.08 09:32) [28]
    Дело в том что в статистике таких полей 7 и справочных запросов 4 штуки со своими условиями. Поэтому было удобно делать через лукап поля.
  • BUM (03.07.08 09:38) [29]

    > 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 место по продажам
  • BUM (03.07.08 09:42) [30]

    > Попробую конечно через
    > 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, ...
    Помойму нето чтото. Надо проверить
  • Sergey13 © (03.07.08 10:00) [31]
    > [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 .....
  • BUM (03.07.08 10:19) [32]
    > 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   // здесь делаю вычисляемое поле LEVEL = RecNo

    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 огромное спасибо! за терпение.
  • Sergey13 © (03.07.08 10:36) [33]
    > [32] BUM   (03.07.08 10:19)
    > Думаю что задачу поставил корректно

    А я так не думаю. В твоих запросах я насчитал штук 5 таблиц, а вопросе фигурировало 2 запроса и вопрос о лукапе к калк полю.
    А как теперь выясняется нужен сводный отчет по манагерам, о которых было известно только то, что у них где-то есть ИД.
  • BUM (03.07.08 10:53) [34]

    > А как теперь выясняется нужен сводный отчет по манагерам,
    >  о которых было известно только то, что у них где-то есть
    > ИД.

    Да вообщем-то бог с ним с отчетом по манагерам.
    Какая разница скока там запросов и таблиц и полей. 1 2 или 3 4 5
    Интересовало именно

    > вопрос о лукапе к калк полю

    100 к 1 что будь там 2 запроса вед. и справ., как я представил, результат будет тотже.
  • Sergey13 © (03.07.08 11:17) [35]
    > [34] BUM   (03.07.08 10:53)
    > Какая разница

    Разница в том, что возможно все решается 1 запросом. Но ты решаешь проблему лукапа, потому что решил делать так как решил.
  • BUM (03.07.08 11:45) [36]

    > Sergey13 ©   (03.07.08 11:17) [35]

    Ок. Буду пытаться решать через объединение первых двух запросов. Спасибо. Тему можно закрывать.
    PS: Что делать, раз в наследство досталась такая структура базы данных, да еще реализованная на Paradox-e со всем богатством возможностей LocalSQL. Хотя зря я, дело давно минувших дней, не ругаться же едучи на паровозе что нельзя обогнать А310.
  • ЮЮ © (03.07.08 12:07) [37]
    > [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 а затем использованеие их в запросе

    При многопользовательском режиме разумно иметь "серверную" и "локальную" БД и использовать механизм гетерогенных запросов.
  • ЮЮ © (03.07.08 12:20) [38]
    Кстати, если обойтись без Calculated в датасете полей,то можно обойтись и механизмом lookup-полей. Только все числа в агрегирующих запросах qn должны считаться SQL-ем.
  • BUM (03.07.08 12:21) [39]

    > самым лучшим со всех точег зрения быдо бы
    > 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 в одной директории на сервере. Не то
 
Конференция "Базы" » LookUp поле по полю Calculate = 0 [D5, Paradox]
Есть новые Нет новых   [134470   +16][b:0][p:0.002]