Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > БД в Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 14.03.2014, 12:39   #1
yu_kuvshinov
 
Регистрация: 14.03.2014
Сообщений: 3
По умолчанию Множество запросов через LEFT OUTER JOIN

Добрый День! как обычно, я начинающий еще только...
нужна помощь, помогите пжл!

есть запрос с кучей LEFT OUTER JOIN для объединения нескольких разных запросов. в каждом запросе по два параметра это (дата от и дата до), они везде одинаковые во всех запросах, берутся из формы.
При выполнении запроса за день, за два отрабатывает норм. А если выполнять за месяц (и необходимо делать это за месяц!!!), то либо висит до бесконечности, либо выдает ошибку:
3.jpg

Код:
begin
  with oraquery2 do
    begin
      close;
      prepare;
      oraquery2.ParamByName('BDate').AsDate:= BDate.Date;
      oraquery2.ParamByName('EDate').AsDate:= EDate.Date;
      oraquery2.Open;
 end;

Вот код запроса:

select sp."Участок"
        ,sp."Группа"
        ,sp."Смена"
        ,sp."Должность"
        ,l.full_name, pb."Прием_брак_новый", ob."отработано_образцов", v."вес", kv."контроль веса", pv."Полное взвешивание"
       ,pop."палеты партия от поставщика"
       ,pop."короба партия от поставщика"
       ,pop."упаковки партия от поставщика"
       ,vf."палеты возвраты филиалов"
       ,vf."короба возвраты филиалов"
       ,vf."упаковки возвраты филиалов"
       ,o."палеты остальные"
       ,o."короба остальные"
       ,o."упаковки остальные"
       ,xx."выработка кладовщика"
       ,ot."Отвлечения"
       ,r."Ручные н/ч"
       ,rr."Авто н/ч"
       ,ta."табель часы"
       ,taa."ночные смены"
from 
(SELECT AGENT.full_name
  FROM sklad.abteilung abteilung,
       sklad.abteilung abteilung_1,
       sklad.AGENT AGENT,
       sklad.beruf beruf
 WHERE abteilung.cd_u = abteilung_1.cd_a
   AND AGENT.beruf = beruf.cd_b
   AND beruf.ein = abteilung.cd_a
   AND ((AGENT.alive = 1))
   and abteilung.cd_a in (162,163,164,201,46)) L 
   
   LEFT OUTER JOIN 
   
   (select count (id.anum) "Прием_брак_новый",a.full_name  
 from stock.ilst il,stock.agent a,stock.idoc id
 where il.quality=2
and il.cd_inspector=a.cd_a
and id.CREATED BETWEEN TO_DATE (:BDate,'DD.MM.RR HH24.MI')
                   AND TO_DATE (:EDate,'DD.MM.RR HH24.MI')
and id.cd_c=il.cd_c and id.cd_a>0
group by a.full_name) pb

on l.full_name = pb.full_name

LEFT OUTER JOIN 


(select count (il.sid) "отработано_образцов",a.full_name
from stock.ilst il,stock.agent a,stock.idoc id
where id.CREATED BETWEEN TO_DATE (:BDate,'DD.MM.RR HH24.MI')
                     AND TO_DATE (:EDate,'DD.MM.RR HH24.MI')
and id.cd_c=il.cd_c and id.cd_a>0
and il.quality=1
and il.cd_inspector=a.cd_a
group by a.full_name) ob
  
on l.full_name = ob.full_name

LEFT OUTER JOIN 

(SELECT   COUNT (lp.cd_c) "вес",
         ag.full_name
    FROM stock.srt2medpak_log lp, SYS.all_users au, stock.AGENT ag
   WHERE lp.date_enter BETWEEN TO_DATE (:BDate,'DD.MM.RR HH24.MI')
                           AND TO_DATE (:EDate,'DD.MM.RR HH24.MI')
     AND lp.user_ = au.username
     AND ag.cd_a = au.user_id
     and lp.vgx_mode = 'Вес'
GROUP BY ag.full_name) v

on l.full_name = v.full_name

LEFT OUTER JOIN 

(SELECT  COUNT (lp.cd_c) "контроль веса",
         ag.full_name
    FROM stock.srt2medpak_log lp, SYS.all_users au, stock.AGENT ag
   WHERE lp.date_enter BETWEEN TO_DATE (:BDate,'DD.MM.RR HH24.MI')
                           AND TO_DATE (:EDate,'DD.MM.RR HH24.MI')
     AND lp.user_ = au.username
     AND ag.cd_a = au.user_id
     and lp.vgx_mode = 'Контроль веса'
GROUP BY ag.full_name) kv

on l.full_name = kv.full_name

LEFT OUTER JOIN 

(SELECT  COUNT (lp.cd_c) "Полное взвешивание",
         ag.full_name
    FROM stock.srt2medpak_log lp, SYS.all_users au, stock.AGENT ag
   WHERE lp.date_enter BETWEEN TO_DATE (:BDate,'DD.MM.RR HH24.MI')
                           AND TO_DATE (:EDate,'DD.MM.RR HH24.MI')
     AND lp.user_ = au.username
     AND ag.cd_a = au.user_id
     and (lp.vgx_mode = 'Полный' or lp.vgx_mode = 'Полный(1)')
GROUP BY ag.full_name) pv

on l.full_name = pv.full_name
 ....
....
и т.д.


Помогите пжл!!! не знаю что не так.... Спасибо!



___________
Код нужно оформлять по правилам:
тегом [CODE]..[/СODE]
(кнопочка на панели форматирования с решёточкой #). Только не забудьте выделить перед этим ваш код программы,
тогда он будет обрамлен нужными тегами:
[CODE]
...
... тут Ваш код программы ...
....
[/ CODE]
Не забывайте об этом!

Модератор.

Последний раз редактировалось Serge_Bliznykov; 14.03.2014 в 12:46.
yu_kuvshinov вне форума Ответить с цитированием
Старый 14.03.2014, 13:01   #2
eval
Подтвердите свой е-майл
 
Регистрация: 29.08.2012
Сообщений: 4,022
По умолчанию

вы смеетесь? кто будет в этой портянке разбираться..
режте по чуть чуть и разбирайтесь
eval вне форума Ответить с цитированием
Старый 14.03.2014, 13:09   #3
yu_kuvshinov
 
Регистрация: 14.03.2014
Сообщений: 3
По умолчанию

Цитата:
Сообщение от eval Посмотреть сообщение
вы смеетесь? кто будет в этой портянке разбираться..
режте по чуть чуть и разбирайтесь
Нет. В этой "потрянке" разбираться не стоит, в ней приведен общий принцип построение запроса. и он работает, если отрабатывать за сутки или двое, а вот ежели за месяц, то липнит или ошибку выдает..
yu_kuvshinov вне форума Ответить с цитированием
Старый 14.03.2014, 13:21   #4
eval
Подтвердите свой е-майл
 
Регистрация: 29.08.2012
Сообщений: 4,022
По умолчанию

ваще av с запросом связывать не стоит, смотрите именно код программы
может гдето обработчики при этих условиях падают...
eval вне форума Ответить с цитированием
Старый 14.03.2014, 13:26   #5
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 19,042
По умолчанию

Начудили с подзапросами. Там вполне можно умньшить их количество. Например заменить три
Код:
    LEFT OUTER JOIN
     (SELECT COUNT (lp.cd_c) "вес", ag.full_name
        FROM stock.srt2medpak_log lp, SYS.all_users au, stock.AGENT ag
        WHERE lp.date_enter BETWEEN TO_DATE (:BDate,'DD.MM.RR HH24.MI') AND TO_DATE (:EDate,'DD.MM.RR HH24.MI') AND
              lp.user_ = au.username AND
              ag.cd_a = au.user_id and
              lp.vgx_mode = 'Вес'
        GROUP BY ag.full_name) v on l.full_name = v.full_name
    LEFT OUTER JOIN
     (SELECT COUNT (lp.cd_c) "контроль веса",ag.full_name
        FROM stock.srt2medpak_log lp, SYS.all_users au, stock.AGENT ag
        WHERE lp.date_enter BETWEEN TO_DATE (:BDate,'DD.MM.RR HH24.MI') AND TO_DATE (:EDate,'DD.MM.RR HH24.MI') AND
              lp.user_ = au.username AND
              ag.cd_a = au.user_id and
              lp.vgx_mode = 'Контроль веса'
        GROUP BY ag.full_name) kv on l.full_name = kv.full_name
    LEFT OUTER JOIN
     (SELECT COUNT (lp.cd_c) "Полное взвешивание",ag.full_name
        FROM stock.srt2medpak_log lp, SYS.all_users au, stock.AGENT ag
        WHERE lp.date_enter BETWEEN TO_DATE (:BDate,'DD.MM.RR HH24.MI') AND TO_DATE (:EDate,'DD.MM.RR HH24.MI') AND
              lp.user_ = au.username AND
              ag.cd_a = au.user_id and
              (lp.vgx_mode = 'Полный' or lp.vgx_mode = 'Полный(1)')
        GROUP BY ag.full_name) pv on l.full_name = pv.full_name
на один
Код:
    LEFT OUTER JOIN
     (SELECT SUM(CASE WHEN lp.vgx_mode = 'Вес' THEN 1 ELSE 0 END) "вес",
             SUM(CASE WHEN lp.vgx_mode = 'Контроль веса' THEN 1 ELSE 0 END) "контроль веса",
             SUM(CASE WHEN lp.vgx_mode = 'Полный' or lp.vgx_mode = 'Полный(1) THEN 1 ELSE 0 END) "Полное взвешивание",
             ag.full_name
        FROM stock.srt2medpak_log lp, SYS.all_users au, stock.AGENT ag
        WHERE lp.date_enter BETWEEN TO_DATE (:BDate,'DD.MM.RR HH24.MI') AND TO_DATE (:EDate,'DD.MM.RR HH24.MI') AND
              lp.user_ = au.username AND
              ag.cd_a = au.user_id
        GROUP BY ag.full_name) v on l.full_name = v.full_name
В других местах аналогично. И очень интересно, как можно работать с такой не форматированной портянкой? Да, и ошибка скорее всего в проге
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 14.03.2014, 14:18   #6
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,515
По умолчанию

1. работа с неиндексированными данными (aget.full_name) как минимум.
все внутренние запросы не нуждаются в оном поле. Достаточно заменить все его вхождения на хорошее индексированное (надеюсь) поле cd_a. И конечно же добавить это поле в ту часть где формируется сам список (в первый подзапрос).

и если только хотите быть совсем защищены от дубликатов по full_name
то сделайте еще одну обертку.
Код:
select full_name, count(?), count(?), count(?), ...
from ( весь ваш запрос )
grop by full_name
Хотя обычно это не требуется. Если имена в справочнике одинаковые, то это еще не означает что это один и тот же агент. А если это так, то виновны те кто ввел его(агента) данные дважды и надо проводить коррекцию данных (делать слияние и удаление).

2. два первых расчета можно объединить в один
Код:
select cd_a, count( case when il.quality=2 then id.anum else NULL end ) "Прием_брак_новый", count( case when il.quality=1 then id.anum else NULL end ) "отработано_образцов"
  from ....
  where ....
    and quality in (1,2)
  group by cd_a, quality
3. аналогично можно поступить с всеми расчетами приведенными далее.

З.Ы. при переходе на с full_name на cd_a можно к тому исключить одно соединение из всех расчетных запросов.
Нам совсем не нужен agent (эта таблица), а вместо cd_a (в выводе и в группировке соответственно) нужно просто брать соответствующее поле связи
il.cd_inspector{=a.cd_a}
программа — запись алгоритма на языке понятном транслятору

Последний раз редактировалось evg_m; 14.03.2014 в 14:25.
evg_m вне форума Ответить с цитированием
Старый 14.03.2014, 16:11   #7
yu_kuvshinov
 
Регистрация: 14.03.2014
Сообщений: 3
По умолчанию

Спасибо ребят!!! ща попробую запросы переделать может поможет...
yu_kuvshinov вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
LEFT JOIN kuba1981 SQL, базы данных 3 21.11.2013 08:00
Left join in Linq romeo.colder C# (си шарп) 0 08.01.2013 11:52
left join kilogram SQL, базы данных 5 14.07.2012 05:13
запрос с left join KatrinSecret SQL, базы данных 2 18.01.2012 22:31
LEFT JOIN acidcool SQL, базы данных 12 20.08.2009 19:23