Конференция "Базы" » Обработка результата запроса [D7, FireBird]
 
  • Xmen (10.02.12 09:31) [0]
    Привет!
    как можно обработать результата запроса.
    Сделал запрос но он долго выполняется. Внутри запроса одно обращение на базу выполняется 10 раз, всегда с разными параметрами. Первый раз выполняется без фильтра. а в остальных запросах выполняется первый запрос только с добавленными параметрами. Как можно воспользоваться ответом первого запроса повторно с разными параметрами.
    Ответ запроса такой его нужно повторно использовать.
    filial |    schet    |  ostatok   | dni
    ____|_________|_________|____
    0010|163099001|45258.01 |65
    0010|163099711|25234.31 |165
    0010|163099921|12258.45 |43
    0010|163099771|89758.99 |655
  • sniknik © (10.02.12 09:55) [1]
    > Первый раз выполняется без фильтра.
    в запросе не фильтр, в запросе условие отбора... а вот желаемое тобой делается как фильтром -
    т.е. получил начальный рекордсет, один раз, наиболее полный, с условием отбора для всех 10 вариантов, а дальше накладываешь на него фильтры для каждого отдельно и используешь "повторно" без обращений к базе.
  • Xmen (10.02.12 10:30) [2]

    > > Первый раз выполняется без фильтра.в запросе не фильтр,
    >  в запросе условие отбора... а вот желаемое тобой делается
    > как фильтром - т.е. получил начальный рекордсет, один раз,
    >  наиболее полный, с условием отбора для всех 10 вариантов,
    >  а дальше накладываешь на него фильтры для каждого отдельно
    > и используешь "повторно" без обращений к базе.

    Именно так но как это сделать?
  • sniknik © (10.02.12 10:38) [3]
    в смысле как? понятия сами за себя говорят...
    условие отбора в запросе, фильтр в рекордсете... дальше конкретика по запросу и используемому компоненту рекордсета.
  • Xmen (10.02.12 12:50) [4]
    Сделал так
         DMForm.qrSaldo.Filtered:=False;
         DMForm.qrSaldo.Filter:='(DNI>60)and(DNI<81)';
         DMForm.qrSaldo.Filtered:=True;
    а как сделать суммирование результата
  • Anatoly Podgoretsky © (10.02.12 13:09) [5]
    > Xmen  (10.02.2012 12:50:04)  [4]

    Не думал что еще есть люди, которые не умеют складывать.
  • Xmen (10.02.12 13:20) [6]

    > Не думал что еще есть люди, которые не умеют складывать.

    :)
    извиняюсь за то что не уточнил вопрос.
    после запроса и ответа у меня уже есть данные в виде

    filial |    schet    |  ostatok   | dni
    ____|_________|_________|____
    0010|163099001|45258.01 |65
    0010|163099711|25234.31 |76
    0010|163099921|12258.45 |63
    0010|163099771|89758.99 |75

    нужно суммировать по полю ostatok в самом query каким то образом
    без изменения селекта и без цикла.
  • sniknik © (10.02.12 13:25) [7]
    >и без цикла
    чудес не бывает.
  • sniknik © (10.02.12 13:28) [8]
    хотя... смотря, что с чем суммировать, может можно сделать вычисляемое поле.
  • Anatoly Podgoretsky © (10.02.12 13:51) [9]
    > Xmen  (10.02.2012 13:20:06)  [6]

    Без цикла никак, он все равно есть, только спрятаный. А чего ты испугался
    цикла, он же быстро работает.
    Про запрос тоже не понятен страх.
  • sniknik © (10.02.12 13:58) [10]
    > Про запрос тоже не понятен страх.
    ИМХО, все как обычно, понаделают тормозов у себя в коде, а после и код "стесняются" показывать, и думают, что тормоза в запросах/фильтрах (мелкософте/борланде) и т.д., только не у себя любимого, вот и ищут "обходные" пути, вместо изучения основ.
  • Xmen (10.02.12 14:16) [11]
    я ранее сделал вот такой запрос
    qoldiq - остаток, sana - дата, ustun - колонка, kun - дни

    select 3 ustun,x.filial, sum(x.qoldiq)
    from (select a.filial, a.acc_external schet,
       (abs(Get_Saldo_Out(a.id, to_date(:sana, 'ddmmyyyy'))) / 100) qoldiq,
       (qol309(a.id,to_date(:sana, 'ddmmyyyy'), abs(Get_Saldo_Out(a.id,to_date(:sana,'ddmmyyyy'))))) kun    
     from accounts a
    where a.filial=:mfo and a.code_coa = '309'
      and Get_Saldo_Out(a.id, to_date(:sana, 'ddmmyyyy')) != 0) x
    group by x.filial
    union
    select 4 ustun,x.filial, sum(x.qoldiq)
    from (select a.filial, a.acc_external schet,
       (abs(Get_Saldo_Out(a.id, to_date(:sana, 'ddmmyyyy'))) / 100) qoldiq,
       (qol309(a.id,to_date(:sana, 'ddmmyyyy'), abs(Get_Saldo_Out(a.id,to_date(:sana,'ddmmyyyy'))))) kun    
     from accounts a
    where a.filial=:mfo and a.code_coa = '309'
      and(substr(acc_external,18,3)>700 and substr(a.acc_external,18,3)<800)
      and Get_Saldo_Out(a.id, to_date(:sana, 'ddmmyyyy')) != 0) x
    group by x.filial  
    union
    select 6 ustun,x.filial, sum(x.qoldiq)
    from (select a.filial, a.acc_external schet,
       (abs(Get_Saldo_Out(a.id, to_date(:sana, 'ddmmyyyy'))) / 100) qoldiq,
       (qol309(a.id,to_date(:sana, 'ddmmyyyy'), abs(Get_Saldo_Out(a.id,to_date(:sana,'ddmmyyyy'))))) kun    
     from accounts a
    where a.filial=:mfo and a.code_coa = '309'
      and bank.Get_Saldo_Out(a.id, to_date(:sana, 'ddmmyyyy')) != 0) x
    where x.kun between 61 and 90
    group by x.filial
    union
    select 7 ustun,x.filial, sum(x.qoldiq)
    from (select a.filial, a.acc_external schet,
       (abs(Get_Saldo_Out(a.id, to_date(:sana, 'ddmmyyyy'))) / 100) qoldiq,
       (qol309(a.id,to_date(:sana, 'ddmmyyyy'), abs(Get_Saldo_Out(a.id,to_date(:sana,'ddmmyyyy'))))) kun    
     from accounts a
    where a.code_filial=:mfo and a.code_coa = '309'
      and(substr(acc_external,18,3)>700 and substr(a.acc_external,18,3)<800)
      and Get_Saldo_Out(a.id, to_date(:sana, 'ddmmyyyy')) != 0) x
    where x.kun between 60 and 90  
    group by x.filial  
    union
    select 9 ustun,x.filial, sum(x.qoldiq)
    from (select a.filial, a.acc_external schet,
       (abs(Get_Saldo_Out(a.id, to_date(:sana, 'ddmmyyyy'))) / 100) qoldiq,
       (qol16309(a.id,to_date(:sana, 'ddmmyyyy'), abs(Get_Saldo_Out(a.id,to_date(:sana,'ddmmyyyy'))))) kun    
     from accounts a
    where a.code_filial=:mfo and a.code_coa = '309'
      and Get_Saldo_Out(a.id, to_date(:sana, 'ddmmyyyy')) != 0) x
    where x.kun between 91 and 180
    group by x.filial
    union
    select 10 ustun,x.filial, sum(x.qoldiq)
    from (select a.code_filial filial, a.acc_external schet,
       (abs(Get_Saldo_Out(a.id, to_date(:sana, 'ddmmyyyy'))) / 100) qoldiq,
       (qol309(a.id,to_date(:sana, 'ddmmyyyy'), abs(Get_Saldo_Out(a.id,to_date(:sana,'ddmmyyyy'))))) kun    
     from accounts a
    where a.code_filial=:mfo and a.code_coa = '309'
      and(substr(acc_external,18,3)>700 and substr(a.acc_external,18,3)<800)
      and Get_Saldo_Out(a.id, to_date(:sana, 'ddmmyyyy')) != 0) x
    where x.kun between 91 and 180  
    group by x.filial  
    union
    select 12 ustun,x.filial, sum(x.qoldiq)
    from (select a.filial, a.acc_external schet,
       (abs(Get_Saldo_Out(a.id, to_date(:sana, 'ddmmyyyy'))) / 100) qoldiq,
       (qol309(a.id,to_date(:sana, 'ddmmyyyy'), abs(Get_Saldo_Out(a.id,to_date(:sana,'ddmmyyyy'))))) kun    
     from accounts a
    where a.filial=:mfo and a.code_coa = '309'
      and Get_Saldo_Out(a.id, to_date(:sana, 'ddmmyyyy')) != 0) x
    where x.kun between 181 and 365
    group by x.filial
    union
    select 13 ustun,x.filial, sum(x.qoldiq)
    from (select a.filial, a.acc_external schet,
       (abs(Get_Saldo_Out(a.id, to_date(:sana, 'ddmmyyyy'))) / 100) qoldiq,
       (qol309(a.id,to_date(:sana, 'ddmmyyyy'), abs(Get_Saldo_Out(a.id,to_date(:sana,'ddmmyyyy'))))) kun    
     from accounts a
    where a.ilial=:mfo and a.code_coa = '16309'
      and(substr(acc_external,18,3)>700 and substr(a.acc_external,18,3)<800)
      and Get_Saldo_Out(a.id, to_date(:sana, 'ddmmyyyy')) != 0) x
    where x.kun between 181 and 365  
    group by x.filial
    union
    select 15 ustun,x.filial, sum(x.qoldiq)
    from (select a.filial, a.acc_external schet,
       (abs(Get_Saldo_Out(a.id, to_date(:sana, 'ddmmyyyy'))) / 100) qoldiq,
       (qol309(a.id,to_date(:sana, 'ddmmyyyy'), abs(Get_Saldo_Out(a.id,to_date(:sana,'ddmmyyyy'))))) kun    
     from accounts a
    where a.filial=:mfo and a.code_coa = '309'
      and Get_Saldo_Out(a.id, to_date(:sana, 'ddmmyyyy')) != 0) x
    where x.kun >365
    group by x.filial
    union
    select 16 ustun,x.filial, sum(x.qoldiq)
    from (select a.filial, a.acc_external schet,
       (abs(Get_Saldo_Out(a.id, to_date(:sana, 'ddmmyyyy'))) / 100) qoldiq,
       (qol309(a.id,to_date(:sana, 'ddmmyyyy'), abs(Get_Saldo_Out(a.id,to_date(:sana,'ddmmyyyy'))))) kun    
     from accounts a
    where a.filial=:mfo and a.code_coa = '309'
      and(substr(acc_external,18,3)>700 and substr(a.acc_external,18,3)<800)
      and Get_Saldo_Out(a.id, to_date(:sana, 'ddmmyyyy')) != 0) x
    where x.kun >365  
    group by x.filial


    запрос работает очень долго 30-45 секунд как можно его оптимизировать?
    наверно заметили внутри селекта есть один селест который повторяется каждый раз как можно сделать так чтобы оно выполнялся один раз а остальные
  • Виталий Панасенко (10.02.12 16:20) [12]
    Тебе ж объяснили - выгреби все, только добавь в список выбираемых полей еще те, которые у тебя в условии этой кучи запросов.. а далее по ним фильтр строй, как в условии запросов...будет один запрос, чуть измененный список полей. а далее уже на клиенте фильтруй в зависимости от нужного. и уже циклом считай. или нужно все сразу? по все филиалам? индексы есть? построй индексы по выражению(computed by)
  • Виталий Панасенко (10.02.12 16:32) [13]
    И зачем выборку делать из подвыборок? Разница между твоим

    select 3 ustun,x.filial, sum(x.qoldiq)
    from (select a.filial, a.acc_external schet,
      (abs(Get_Saldo_Out(a.id, to_date(:sana, 'ddmmyyyy'))) / 100) qoldiq,
      (qol309(a.id,to_date(:sana, 'ddmmyyyy'), abs(Get_Saldo_Out(a.id,to_date(:sana,'ddmmyyyy'))))) kun    
    from accounts a
    where a.filial=:mfo and a.code_coa = '309'
     and Get_Saldo_Out(a.id, to_date(:sana, 'ddmmyyyy')) != 0) x
    group by x.filial



    и этим есть ?

    select 3 ustun a.filial,
      sum((abs(Get_Saldo_Out(a.id, to_date(:sana, 'ddmmyyyy'))) / 100)) qoldiq
    from accounts a
    where a.filial=:mfo and a.code_coa = '309'
     and Get_Saldo_Out(a.id, to_date(:sana, 'ddmmyyyy')) != 0
    group by x.filial

  • Виталий Панасенко (10.02.12 16:44) [14]
    + хранимки.. не лучше ли использовать execute block, вычислить исх.остаток один раз и его значение использовать?
  • Виталий Панасенко (10.02.12 17:02) [15]
    я  так понимаю, qol309 тоже ХП у которой второй параметр - тоже ХП. и получаемое тут
    (qol309(a.id,to_date(:sana, 'ddmmyyyy'), abs(Get_Saldo_Out(a.id,to_date(:sana,'ddmmyyyy'))))) kun


    значение абсолютно тебе не интересует.. а ХП то все равно выполняется. 40 раз.. буквально.. в моем примере будет 20
  • makz (11.02.12 12:16) [16]

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

    Обрати внимание на производные таблицы
    http://www.ibprovider.com/rus/documentation/firebird_20_adonet.html
  • Xmen (12.02.12 15:15) [17]

    > Виталий Панасенко   (10.02.12 17:02) [15]
    >
    > я  так понимаю, qol309 тоже ХП у которой второй параметр
    > - тоже ХП. и получаемое тут
    > (qol309(a.id,to_date(:sana, 'ddmmyyyy'), abs(Get_Saldo_Out(a.
    > id,to_date(:sana,'ddmmyyyy'))))) kun
    > значение абсолютно тебе не интересует.. а ХП то все равно
    > выполняется. 40 раз.. буквально.. в моем примере будет 20

    Интересует.
    qoldiq это сумма остатка
    kun это дни остатков то есть дни задолженностей.

    И извиняюсь база Oracle.
  • Кщд (13.02.12 08:04) [18]
    >Xmen   (10.02.12 14:16) [11]
    переписать с одним обращением к accounts - безо всяких union
  • Виталий Панасенко (13.02.12 12:28) [19]

    > Xmen   (12.02.12 15:15) [17]
    >
    >

    Интересно.. а в запросе не видно чтобы интересовало
 
Конференция "Базы" » Обработка результата запроса [D7, FireBird]
Есть новые Нет новых   [134431   +11][b:0][p:0.003]