Помогите исправить прямой SQL.

Программирование на Атлантисе (VIP, FCOM, ARD), FastReport

Модераторы: m0p3e, edward_K, Модераторы

Ответить
denisag
Постоянный гость
Сообщения: 59
Зарегистрирован: 02 дек 2011, 14:28

Помогите исправить прямой SQL.

Сообщение denisag »

Всем доброго дня.
Совсем запутался я в попытке оптимизации SQL запроса, поэтому прошу помощи
Вот этот запрос - правильно отрабатывает в саппорте

Код: Выделить всё

 select KATSOPR.NSOPR,
	   KATSOPR.DSOPR,
	   KATMC.NAME,
    SPORDER.KOL,
	   SPSOPR.PRICE,
    katorg2.name,
	   KATORG.NAME,
	   KATPARTY.NAME,
	   SKLORDER.NORDER,
	   KATPODR.NAME,
	   KATORG.ADDR
from KATSOPR,
     SPSOPR,
     KATORG,
     KATPARTY,
     SKLORDER,
     SPORDER,
     KATPODR,
     KATORG katorg2,
     KATMC
where
((
201 == KATSOPR.VIDSOPR and
KATSOPR.NREC == SPSOPR.CSOPR   and
KATSOPR.CORGBASE == KATORG.NREC and
SPSOPR.CMCUSL == KATMC.NREC and
1 == SPSOPR.PRMC and
SPSOPR.CPARTY == KATPARTY.NREC and
SPSOPR.NREC == SPORDER.CSPSOPR and
SPORDER.CSKLORDER == SKLORDER.NREC and
SKLORDER.CPODR == KATPODR.NREC  and
KATSOPR.CGRUZTO == katorg2.NREC
)); 
А это я попытался его же оптимизировать и выполнять в квери аналайзере - для того чтобы потом вставить в код как прямой SQL для заполнения временной таблицы

Код: Выделить всё

use Test_Rus
select t.F$NSOPR '№ накладной', 
	   t.F$DSOPR 'Дата накладной',
	   t6.F$NORDER '№ ордера',
	   t2.F$NAME 'Наименование товара',
	   t5.F$NAME  'Наименование партии',
	   t1.F$PRICE 'Цена за еденицу',
	   t4.F$KOL   'Кол-во отгруженного товара',
	   t31.F$NAME 'Наименование грузополучателя',
	   t31.F$ADDR 'адрес грузополучателя',
	   t3.F$NAME  'Наименование контрагента',
	   t7.F$NAME  'Название склада'
from T$SPSOPR as t1
	 INNER JOIN T$KATSOPR as t
	 ON t.F$NREC = t1.F$CSOPR
	 INNER JOIN T$KATMC as t2
	 ON t1.F$CMCUSL = t2.F$NREC
	 INNER JOIN T$SPORDER as t4
	 ON t1.F$NREC = t4.F$CSPSOPR
	 LEFT JOIN T$KATPARTY as t5
	 ON t1.F$CPARTY = t5.F$NREC
	 INNER JOIN T$SKLORDER as t6
	 ON t4.F$CSKLORDER = t6.F$NREC
	 INNER JOIN T$KATPODR as t7
	 ON t6.F$CPODR = t7.F$NREC,
     T$KATORG as t3
     INNER JOIN T$KATSOPR as tn
     ON tn.F$CORGBASE = t3.F$NREC,
     T$KATSOPR as tnn
     INNER JOIN T$KATORG as t31
     ON tnn.F$CGRUZTO = t31.F$NREC
where 201 = t.F$VIDSOPR and
      1 = t1.F$PRMC     
Этот запрос выводить очень много строк, так как я видно чего то перепутал в Joinах.
Так же если подправить не оптимизированный запрос он также выводит неверные данные, тк есть записи у которых нет наименования партии и это нормально. В общем прошу помощи чтобы разобраться.
RAJAH
Местный житель
Сообщения: 932
Зарегистрирован: 18 фев 2008, 12:49

Re: Помогите исправить прямой SQL.

Сообщение RAJAH »

Во-первых, я бы поменял эту строку, т.к. считаю, что нужно связывать между собой документы, а не их позиции (т.е. SKLORDER и KATSOPR):
denisag писал(а):

Код: Выделить всё

SPSOPR.NREC == SPORDER.CSPSOPR and
Во-вторых, мне не понятно: зачем ВСЕ накладные на продажу? Наверное, нужны какие-то временные рамки по KATSOPR.DOPR, будет быстрее работать, думаю.
У меня так получилось:

Код: Выделить всё

((
DBEGIN  <<= KATSOPR.DOPR and
DEND >>= KATSOPR.DOPR and
201 == KATSOPR.VIDSOPR and
KATSOPR.NREC == SPSOPR.CSOPR   and
KATSOPR.CORGBASE == KATORG.NREC and
SPSOPR.CMCUSL == KATMC.NREC and
1 == SPSOPR.PRMC and
SPSOPR.CPARTY == KATPARTY.NREC and
KATSOPR.NREC == SKLORDER.CSOPR AND
SKLORDER.NREC == SPORDER.CSKLORDER and
SKLORDER.CPODR == KATPODR.NREC  and
KATSOPR.CGRUZTO == katorg2.NREC
));
В-третьих, LEFT JOIN это, грубо говоря, аналог "==", а INNER JOIN - "/==". У вас "мягкие" подцепки в первом запросе, а во втором INNER встречаются.
edward_K
Заслуженный деятель интернет-сообщества
Сообщения: 5188
Зарегистрирован: 29 мар 2005, 17:49
Откуда: SPB galaxy spb

Re: Помогите исправить прямой SQL.

Сообщение edward_K »

Код: Выделить всё

    T$KATORG as t3
     INNER JOIN T$KATSOPR as tn
     ON tn.F$CORGBASE = t3.F$NREC,
     T$KATSOPR as tnn
     INNER JOIN T$KATORG as t31
     ON tnn.F$CGRUZTO = t31.F$NREC
вот это как то неправильно T$KATORG as t3 и T$KATSOPR as tnn подвисли в воздухе. Правильней сначала перечислить все нужные таблицы во from и на забыть их завязать через where, а потом уже все через INNER JOIN. А лучше всегда во form держать одну таблицу, в where накладывать условия только на нее и вычисляемые поля, а остальное через JOIN.
Как то так
From ...
????? Join ..
....
????? Join ...
where ...
INNER аналогичен жесткой подцепке в галактике. Если ее не требуется используйте Left outer.
Den
Местный житель
Сообщения: 1844
Зарегистрирован: 29 мар 2005, 17:49
Откуда: Ярославская область ОАО "Часовой завод Чайка" г. Углич
Контактная информация:

Re: Помогите исправить прямой SQL.

Сообщение Den »

Зачем стока раз декларируете katsopr под элиасами
...
T$KATORG as t3
INNER JOIN T$KATSOPR as tn
ON tn.F$CORGBASE = t3.F$NREC,
T$KATSOPR as tnn
INNER JOIN T$KATORG as t31
ON tnn.F$CGRUZTO = t31.F$NREC
...

У Вас же в самом начале уже есть :

INNER JOIN T$KATSOPR as t

к нему и join делаейте:
INNER JOIN T$KATORG as t3
ON t.F$CORGBASE = t3.F$NREC
INNER JOIN T$KATORG as t31
ON t.F$CGRUZTO = t31.F$NREC
.....

и все что от T$KATSOPR as t join-ньте не по inner a left , абы не потерять часть katsopr-а
Последний раз редактировалось Den 20 янв 2012, 16:14, всего редактировалось 1 раз.
denisag
Постоянный гость
Сообщения: 59
Зарегистрирован: 02 дек 2011, 14:28

Re: Помогите исправить прямой SQL.

Сообщение denisag »

Нужны именно все накладные.
Это будет таблица некоего первого интерфейса из которого можно вызвать второй интерфейс с таблицей грузополучателей выбрав который в первой таблице останется информация только по нему.
Когда все будет готово оформлю в опыте.
denisag
Постоянный гость
Сообщения: 59
Зарегистрирован: 02 дек 2011, 14:28

Re: Помогите исправить прямой SQL.

Сообщение denisag »

В общем я в конец запутался.
Давайте снова:
мне нравится как такой код отрабатывает в сапорте

Код: Выделить всё

select KATSOPR.NSOPR,
	   KATSOPR.DSOPR,
	   KATMC.NAME,
    SPORDER.KOL,
	   SPSOPR.PRICE,
    katorg2.name,
	   KATORG.NAME,
	   KATPARTY.NAME,
	   SKLORDER.NORDER,
	   KATPODR.NAME,
	   KATORG.ADDR
from KATSOPR,
     SPSOPR,
     KATORG,
     KATPARTY,
     SKLORDER,
     SPORDER,
     KATPODR,
     KATORG katorg2,
     KATMC
where
((
201 == KATSOPR.VIDSOPR and
KATSOPR.NREC /== SPSOPR.CSOPR   and
KATSOPR.CORGBASE == KATORG.NREC and
SPSOPR.CMCUSL == KATMC.NREC and
1 == SPSOPR.PRMC and
SPSOPR.CPARTY == KATPARTY.NREC and
KATSOPR.NREC == SKLORDER.CSOPR AND
SKLORDER.NREC == SPORDER.CSKLORDER and
SKLORDER.CPODR == KATPODR.NREC  and
KATSOPR.CGRUZTO == katorg2.NREC
));                                  
Если его же выполнить в квери то получится фигня:

Код: Выделить всё

use Test_Rus
 select T$KATSOPR.F$NSOPR,
	    T$KATSOPR.F$DSOPR,
	    T$KATMC.F$NAME,
            T$SPORDER.F$KOL,
	    T$SPSOPR.F$PRICE,
             katorg2.F$NAME,
	    T$KATORG.F$NAME,
	    T$KATPARTY.F$NAME,
	    T$SKLORDER.F$NORDER,
	    T$KATPODR.F$NAME,
	    T$KATORG.F$ADDR
from T$KATSOPR,
     T$SPSOPR,
     T$KATORG,
     T$KATPARTY,
     T$SKLORDER,
     T$SPORDER,
     T$KATPODR,
     T$KATORG katorg2,
     T$KATMC
where
201 = T$KATSOPR.F$VIDSOPR and
T$KATSOPR.F$NREC = T$SPSOPR.F$CSOPR   and
T$KATSOPR.F$CORGBASE = T$KATORG.F$NREC and
T$SPSOPR.F$CMCUSL = T$KATMC.F$NREC and
1 = T$SPSOPR.F$PRMC and
T$SPSOPR.F$CPARTY = T$KATPARTY.F$NREC and
T$KATSOPR.F$NREC = T$SKLORDER.F$CSOPR AND
T$SKLORDER.F$NREC = T$SPORDER.F$CSKLORDER and
T$SKLORDER.F$CPODR = T$KATPODR.F$NREC  and
T$KATSOPR.F$CGRUZTO = katorg2.F$NREC
Собственно мне нужно добиться такого же результата в квери как и в саппорте и переделать запрос для использования с джоинами так как на реальных данных такой селект выполняется достаточно долго.
Прошу помощи - пока то что написали не особо понял, плотнячком с БД работаю пару месяцев :?:
RAJAH
Местный житель
Сообщения: 932
Зарегистрирован: 18 фев 2008, 12:49

Re: Помогите исправить прямой SQL.

Сообщение RAJAH »

denisag писал(а):Это будет таблица некоего первого интерфейса из которого можно вызвать второй интерфейс с таблицей грузополучателей выбрав который в первой таблице останется информация только по нему.
denisag писал(а):такой селект выполняется достаточно долго.
Естественно! :grin: Зачем выбирать данные, чтобы потом их удалять? Надо первый интерфейс делать менее подробным и цеплять остальные таблицы только при вызове второго. Посмотрите на интерфейс накладных в "Галактике": просто список с основными параметрами, а подробности можно увидеть, открыв нужный (а не все сразу) документ.
n0where
Местный житель
Сообщения: 499
Зарегистрирован: 30 дек 2010, 08:16

Re: Помогите исправить прямой SQL.

Сообщение n0where »

мне нравится как такой код отрабатывает в сапорте
А мне не нравится. он у меня выполняется более 4 минут

Перевел на DSQL (на вскидку без оптимизации) и о чудо он выполнился (выполнил в саппорте) за 7 секунд (более 200000 записей)

Код: Выделить всё

sql select
KATSOPR.NSOPR,
KATSOPR.DSOPR,
KATMC.NAME,
SPORDER.KOL,
SPSOPR.PRICE,
katorg2.name,
KATORG1.NAME,
KATPARTY.NAME,
SKLORDER.NORDER,
KATPODR.NAME,
KATORG1.ADDR
from
KATSOPR
INNER JOIN SPSOPR on KATSOPR.NREC = SPSOPR.CSOPR and 1 = SPSOPR.PRMC
INNER JOIN SKLORDER on KATSOPR.NREC = SKLORDER.CSOPR
INNER JOIN SPORDER on SPORDER.CSPSOPR = SPSOPR.NREC
LEFT OUTER JOIN KATORG as KATORG1 on KATSOPR.CORGBASE = KATORG1.NREC
LEFT OUTER JOIN KATORG as KATORG2 on KATSOPR.CGRUZTO = katorg2.NREC
LEFT OUTER JOIN KATMC on SPORDER.CMC = KATMC.NREC
LEFT OUTER JOIN KATPARTY on SPORDER.CPARTY = KATPARTY.NREC
LEFT OUTER JOIN KATPODR on SPORDER.CCPODR = KATPODR.NREC
where
201 = KATSOPR.VIDSOPR
;
хороший программист — это человек, который переходя улицу с односторонним движением смотрит в обе стороны
denisag
Постоянный гость
Сообщения: 59
Зарегистрирован: 02 дек 2011, 14:28

Re: Помогите исправить прямой SQL.

Сообщение denisag »

СПАСИБО!, Мне тоже так больше нравится :grin:
Все работает и даже в квери))
Ответить