Страница 1 из 2
Правильный порядок в подцепке
Добавлено: 07 дек 2004, 00:43
Nick
Как правильно объяснить то, что запрос:
Select
KatSopr.NSopr, KatSopr.DSopr,
SpSopr.Npp, SpSopr.KolFact, SpSopr.Price,
KatMc.Name
Where
((
101 /== KatSopr.VidSopr
and KatSopr.Nrec /== SpSopr.cSopr
and SpSopr.cMcUsl /== KatMc.Nrec
));
корректно выводит список приходных накладных с их спецификациями, а если в подцепке в последней строке поменять местами правую и левую часть: and KatMc.Nrec /== SpSopr.cMcUsl - то ничего в результат не попадает вообще.
Как понять правильно? В подцепке ведь слева стоит корневая таблица, а справа та, которая к ней цепляется (указывает на нее ссылкой)? или все-равно кто где?
Т.е. во второй строке правило соблюдено, а в третьей все наоборот.
Константы обязательно слева еще вроде как.
Где почитать?
Re: Правильный порядок в подцепке
Добавлено: 07 дек 2004, 11:07
edward_K
1. при выборе получается декартово произведение записей в katsopr и katmc.
2.логичней тогда и другие строки переписать
101 == Spsopr.vidsopr and
1 == spsopr.prmc and
katmc.nrec == spsopr.cmcusl and
spsopr.csopr == katsopr.nrec
Re: Правильный порядок в подцепке
Добавлено: 15 дек 2004, 18:14
Nick
Честно говоря, я не понял причем здесь декартово произведение записей - если не трудно - поясните пожалуйста.
А вот прочитал:
"...Конструкция Where позволяет не только накладывать ограничения на результат выборки, но и связывать таблицы. Необходимость связывать таблицы может понадобиться при извлечении данных сразу из нескольких таблиц. Связывание двух таблиц называется подцепкой.
Каждая подцепка устанавливает соответствие между отдельным полем подчиненной таблицы и полем родительской таблицы. Подцепка косвенным образом определяет индекс, который подбирается базой данных.
Для определения связи между полями родительской и подчиненной таблиц применяются специальные наборы символов:
==, /==, >>=, <<=, >>, <<
Слева от условия связи задаются выражения, которые могут содержать поле родительской таблицы и константы, а справа - поле подчиненной таблицы и атрибуты.
Реляционные связи могут быть двух типов - жесткие и мягкие.
При мягкой подцепке отсутствующие в подчиненной таблице записи заполняются значениеми по умолчанию. При жесткой подцепке записи родительской таблицы, для которых не были найдены записи в таблице-потомке, в выборку не попадают.
Еще я понял, что подцепка - это то, что заключено в скобки (( и )) и выполняется она на сервере, в отличие от фильтрации: того, что за этими скобками - выполняется на клиенте.
Таким образом:
KatMc.Nrec /== SpSopr.cMcUsl
более верная запись в подцепке, чем
SpSopr.cMcUsl /== KatMc.Nrec
Так как SpSopr - подчиненная таблица для KatMc - ведь спецификация накладной ссылается на МЦ, но работоспособный именно второй вариант ???
Re: Правильный порядок в подцепке
Добавлено: 15 дек 2004, 18:50
Nick
Проверил на работе:
Select
KatSopr.NSopr, KatSopr.DSopr,
SpSopr.Npp, SpSopr.KolFact, SpSopr.Price,
KatMc.Name
Where
(( 101 /== KatSopr.VidSopr
and KatSopr.Nrec /== SpSopr.cSopr
and SpSopr.cMcUsl /== KatMc.Nrec
))
and (KatSopr.DSopr >= '31/01/2004')
;
Работает и так:
and SpSopr.cMcUsl /== KatMc.Nrec
и так:
and KatMc.Nrec /== SpSopr.cMcUsl
Правда второй вариант гораздо дольше выполняется (260 сек. против 8 сек. в первом случае). Почему так, ведь в теории второй вариант правильнее - слева главная таблица, справа - подчиненная?
Такой вопрос - вообще как работает подцепка? Есть, например, записи в SpSopr и записи в KatMc.
При SpSopr.cMcUsl /== KatMc.Nrec Галактика проходит по SpSopr и:
1. Берет текущее SpSopr.cMcUsl
2. Проходит с текущей SpSopr.cMcUsl по KatMc и цепляет записи KatMc, где SpSopr.cMcUsl = KatMc.Nrec
Получем табличку:
SpSopr - KatMc
SpSopr - KatMc
...
SpSopr - KatMc
При KatMc.Nrec /== SpSopr.cMcUsl Галактика проходит по KatMc и:
1. Берет текущее KatMc.Nrec
2. Проходит с текущей KatMc.Nrec по SpSopr и цепляет записи KatMc, где KatMc.Nrec = SpSopr.cMcUsl
Получем табличку:
KatMc - SpSopr
KatMc - SpSopr
...
KatMc - SpSopr
Т.е. если имеем:
SpSopr KatMc
A 1,2,3
B 4,5
То в первом случае получим:
A - 1
A - 2
A - 3
B - 4
B - 5
Во втором случае получим:
1 - A
2 - A
3 - A
4 - B
5 - B
Это и есть декартово произведение? Результат-то один, но почему скорости разные и правила жесткие в подцепке на расположение таблиц родительских и подчиненных, если в результате получаем один результат?
Re: Правильный порядок в подцепке
Добавлено: 15 дек 2004, 18:57
Maverick
Святая простота... )))
KatMc.Nrec /== SpSopr.cMcUsl означает лишь отразить те записи из SPSOPR которые есть на данный момент в KatMC, причем KatMC - корневая таблица по отношению к SPSOPR ... При этом нужно еще и не забыть фильтр в SPSOPR по PRMC (что еэто - именно товар - иначе при совпадении нреков могут и услуги отобразиться)
SpSopr.cMcUsl /== KatMc.Nrec - наоборот, отобразить только то, что есть в спецификации - тогда корень - SPSOPR? подчиненная - KATMC.
А вообще, я бы не советовал жесткими подцепками пользоваться имхо - а) устаревшая конструкция б) тормозит жутко...
А по сути
Select
KatSopr.NSopr, KatSopr.DSopr,
SpSopr.Npp, SpSopr.KolFact, SpSopr.Price,
KatMc.Name
Where
((
101 /== KatSopr.VidSopr
and KatSopr.Nrec /== SpSopr.cSopr
and SpSopr.cMcUsl /== KatMc.Nrec
));
лучше писать так
Select
KatSopr.NSopr, KatSopr.DSopr,
SpSopr.Npp, SpSopr.KolFact, SpSopr.Price,
KatMc.Name
Where
((
Word(101) == KatSopr.VidSopr
and KatSopr.Nrec == SpSopr.cSopr
and SpSopr.cMcUsl == KatMc.Nrec
));
таким образом данный селект отобразит шапку накладных (номер и дату накладнной)по типу 101, по моему - приходые накладные(KATSOPR), спецификацию (номер п/п, кол-во и цену) по каждой накладной (SPSOPR) где кажой записи из KatSopr будет соответствовать группа записей из SPSopr (1 к N), и МЦ , соответствующую кажддой позиции накладной (KATMC) при этом каждой позиции в SPSOPR соответствует 1 запись из KATMC (связь 1 к 1).
В случае обычного запроса получится плоская табличка с кол-вом записей S*N, где S- кол-во записей в KATSOPR, а S - кол-во записей SPSOPR соответствующее каждой позиции из KATSOPR (KATMC в расчет не берется т.к. связь 1 к 1).
В случае обработки из випа имеем пробежку по корневой KATSOPR - внутри нее - пробежку по SPSOPR а внутри последней - проверка наличия записи в KATMC
Re: Правильный порядок в подцепке
Добавлено: 15 дек 2004, 19:03
Maverick
Какая таблица является корневой - определяется задачей, которую необходимо решить - из данного селекта видно что тебе нужно получить соответствие спецификация - МЦ, т.е. отразить МЦ, которые есть в спецификации - сл-но корневой и должна быть спецификация накладной.
запись наоборот означает что ты пытаешься найти соответствия МЦ-спецификация, т.е. для каждой МЦ из справочника проверяешь, есть ли она в спецификации.. а это имхо - бред, т.к. спецификация формируется именно из справочника
Re: Правильный порядок в подцепке
Добавлено: 16 дек 2004, 16:33
bublik
Ув., Maverick! А не подскажете ли как правильно формировать и как работают подцепки в КОРПО-ЗАПРОСАХ ? Вот уж где действительно "темный лес" !!!!!! Может вы "осветите" этот вопрос? Более подробно я описал его в "администраторском форуме". Прошу пардона что влез в вашу разговор...
Re: Правильный порядок в подцепке
Добавлено: 16 дек 2004, 16:58
ecasoft
SQL Галактики такой вот
В WHERE (( )) справа от == (или от <<=, >>=,>>,<<) стоит таблица, которая зависит от значения поля, указанного слева. Если таблица стоит несколько раз справа, то все поля, по которым она подцеплена к левой стороне образуют так называемы составной индекс (должен быть описан в словаре). Такую талицу еще называют узлом. К узлу можно подвесить еще и не индексные условия..
....
WORD(1) == SpSopr.PrMc and
KatMc.Nrec == SpSOpr.cMcUsl
(SpSopr.atl_lastdate = cur_date) and
....
ТАКИМ ОБРАЗОМ, в Галактике, Вы программируете не обычным SQL, а так бы подсказываете интерпретатору, какой поиск использовать явно. При этом стоя эффективный SQl запрос Вы должны отталкиваться от наличия индексов в БД.
Тем, кто рашьне не "помогал" SQL -серверу..все это покажется странным..это нормально.
Re: Правильный порядок в подцепке
Добавлено: 16 дек 2004, 17:54
bublik
А как же с подцепками в запросах корпо-обмена? Неужели никто не знает как ЭТО работает? Или только мы одни пользуемся запросами в корпообмене?
Re: Правильный порядок в подцепке
Добавлено: 16 дек 2004, 17:59
Maverick
в обчем, тезка правильно осветил вопрос - емко и в двух словах )))
а еще - RTFM ))) тока очень внимательно )))
по факту то что он сказал можно разделить на две части
а) ограничение на таблицу
слева константа - справа таблица. соединение через ==
б) подцепка через индексное выражение
слева - поле (поля) корневой таблицы, правал - подчиненной. причем порядок полей слева должен в точности до некоторой позиции составлять один ихз существующих индексов. в случае отличия порядка следования полей от порядка, определяемого одним из индексных выражений будет злостная ругань со стороны компилятора. этого можно ихзбежать если использовать вместо == знак = и выражение заключать в скобки. это будет фильтр. только он очень тормозит. луче после несовпадающей с индесом связки писать (noindex)/ но как я понимаю, до этого вам еще далеко
Re: Правильный порядок в подцепке
Добавлено: 16 дек 2004, 18:01
ecasoft
Мы не пользовались. Как-то не нужно было. Да и вообще с корпо мало работаем - большенство на одной площадке сидят. А если удаленно - то полный обмен. Обычно, если удаленное юр. лицо, то полный обмен в ее базу, а с этой базой уже стыкуется головная по документам (типа экспорт-импорт). Удаленных складов чего-то не стало...все протянули провода
Re: Правильный порядок в подцепке
Добавлено: 17 дек 2004, 12:25
sth
подцепки в корпо работают также как и в обычном галактическом sql. по сути, это он и есть.
Re: Правильный порядок в подцепке
Добавлено: 20 дек 2004, 17:38
Priest Geo
В первом случае когда мы имеем подцепку:
...
Where
(( 101 /== KatSopr.VidSopr
and KatSopr.Nrec /== SpSopr.cSopr
and SpSopr.cMcUsl /== KatMc.Nrec ))
просматриваются по порядку ВСЕ SpSopr; берётся первая запись SpSopr и ЕДИНСТВЕННАЯ запись KatMC (по NREC, а раз это по индексу - это быстренько находится)
Во втором случае:
...
Where
(( 101 /== KatSopr.VidSopr
and KatSopr.Nrec /== SpSopr.cSopr
and KatMc.Nrec /== SpSopr.cMcUsl ))
перебираются по очереди ВСЕ записи KatMC и если находится такой что KatMC.Nrec = SpSopr.cMcUsl, то запись оставляется в покое и берётся следующая SpSopr и всё начинается сначала, иначе текущий SpSopr игнорируется.
Вот если бы запрос был немного другой:
...
Where
(( '00001' == KatMC.Barkod
and 101 /== KatSopr.VidSopr
and KatSopr.Nrec /== SpSopr.cSopr
and KatMc.Nrec /== SpSopr.cMcUsl ))
или
...
Where
((
Word(7) == Pick.wList
// выборка полученная через RunInterface('GetSomeMC', (-12345))
and Pick.cRec == KatMC.Nrec
and 101 /== KatSopr.VidSopr
and KatSopr.Nrec /== SpSopr.cSopr
and KatMc.Nrec /== SpSopr.cMcUsl ))
тогда такой запрос имело бы смысл писать, хотя эффективнее изменить его на такой:
...
Where
((
Word(7) == Pick.wList
and word(101) == SpSopr.VidSopr
and Pick.cRec == SpSopr.cMcUsl
and Pick.cRec == KatSopr.Nrec // это если нужно название МЦ
and SpSopr.cSopr == KatSopr.Nrec // это для номера накладной (dSopr есть и в SpSopr)
))
Re: Правильный порядок в подцепке
Добавлено: 24 дек 2004, 20:09
Nick
Спасибо всем ответившим
Вроде как разобрался.
Такой вопрос возник по индексам: Выцепляю из накладной, помимо всего, Товарно-транспортную информацию (наименование пункта погрузки):
Select
KatSopr.NSopr, KatSopr.DSopr,
MarPunkt.Name,
SpSopr.Npp, SpSopr.KolFact, SpSopr.Price,
KatMc.Name
Where
((
101 == KatSopr.VidSopr
and KatSopr.nRec == TTNDOC.cDoc (NoIndex)
and TTNDoc.cPunktP == MarPunkt.nRec
and KatSopr.nRec == SpSopr.cSopr
and SpSopr.cMcUsl == KatMc.nRec
));
Хочется все-таки использовать индекс для TTNDoc. У нее есть ближайший похожий: TTNDOC02 - по двум полям: WTABLE и CDOC.
Хочу добавить в выборку строку word(1) << TTNDoc.wTable чтобы все попадало по этому условию в результат, и индекс использовался.
Но Галактика дает этого сделать - ругается, что нужен ключ по WTable + cDoc для TTNDoc ???
А если заменить эту строчку на word(1) == TTNDoc.wTable - нормально все проходит, но естественно в результат ничего не попадает.
Подскажите, можно ли решить, или придется использовать все-таки NoIndex ?
Re: Правильный порядок в подцепке
Добавлено: 27 дек 2004, 11:34
bublik
> sth
> подцепки в корпо работают также как и в
>обычном галактическом sql. по сути, это он
>и есть
Запрос - он везде запрос. И по сути ВСЕ ЗАПРОСЫ работают как ЗАПРОСЫ, т.е. с подцепками, "фильтрацией", "индексами и т.д.
Только вот ПОСТРОЕНИЕ и ФУНКЦИОНИРОВАНИЕ КОРПО-ЗАПРОСА это соооовсем иное. Напишите "по сути" тот же корпо запрос в явном виде в SQL и вы .... НИЧЕГО НЕ ПОЛУЧИТЕ, или же получите БОООЛьшой ступор системы! SQL запрос работает напрямую с таблицами и это РЕАЛЬНЫЙ ЗАПРОС. КОРПО-ЗАПРОС - это построитель/описатель выборок, но никак НЕ ЯВНЫЙ ЗАПРОС! И как я понял, тот кто знал как это работает давно уже помер...
И работает этот запрос не с таблицами, а с журналом - это факт!