powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Как правильно применить INNER JOIN под VFP98?
22 сообщений из 22, страница 1 из 1
Как правильно применить INNER JOIN под VFP98?
    #32369942
Фотография neznajka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Братцы, подскажите: если имеется (“adr.dbf”) dbf-ник с кодом города, кодом улицы и номером дома, а также есть 2 словарных dbf-ника с расшифровкой кода города (“gor.dbf”) и кода улицы (“ul.dbf”), то можно ли ОДНИМ SQL-запросом с INNER JOIN получить раскодированную итоговую таблицу? У меня это получается только ДВУМЯ запросами – по очереди «подшивая» каждый из словарей, а в HELPе на VFP98 намекается (если я правильно понял) , что такие фокусы можно проделывать за один этап… Но запрос типа:
SELECT B.GOROD, C.ULICA, A.DOM FROM ADR A ;
INNER JOIN GOR B ;
INNER JOIN UL C ;
ON A.KOD_GOR=B.KOD ;
ON A.KOD_UL=C.KOD
дает неверный результат во 2-м поле итоговой таблицы.
...
Рейтинг: 0 / 0
Как правильно применить INNER JOIN под VFP98?
    #32370039
vl2000
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Попробуй так:
SELECT G.GOROD, U.ULICA, A.DOM FROM UL U ;
RIGHT OUTER JOIN ADR A ;
LEFT OUTER JOIN GOR G ;
ON G.KOD_GOR=A.KOD_GOR ;
ON A.KOD_UL=U.KOD_UL

А вот как сделать то же самое, но для трёх справочников?
...
Рейтинг: 0 / 0
Как правильно применить INNER JOIN под VFP98?
    #32370041
Фотография neznajka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо, vl2000 . Сейчас попробую - вижу, что пойдет. Ну а насчет произвольного количества справочников - думаю, это трудновато. В прошлом году я был вынужден сочинить пользовательскую функцию для частного случая с 4-мя справочниками. Но она себя не оправдывает - уж лучше в таких случаях применять поэтапное SQL SELECT-ирование для каждого справочника (или для каждой пары справочников по Вашему варианту).
...
Рейтинг: 0 / 0
Как правильно применить INNER JOIN под VFP98?
    #32370778
coolkenga
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
А разве условие по которому две таблицы соединяются (то, что после on) нужно не сразу после конкретного join-а
Код: plaintext
1.
2.
3.
4.
SELECT B.GOROD, C.ULICA, A.DOM FROM ADR A ; 
INNER JOIN GOR B ; 
ON A.KOD_GOR=B.KOD ;
INNER JOIN UL C ; 
ON A.KOD_UL=C.KOD 
...
Рейтинг: 0 / 0
Как правильно применить INNER JOIN под VFP98?
    #32370787
coolkenga
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
еще можно без inner join-а
Код: plaintext
1.
2.
SELECT B.GOROD, C.ULICA, A.DOM ;
FROM ADR A, GOR B, UL C ; 
WHERE A.KOD_GOR=B.KOD AND A.KOD_UL=C.KOD
...
Рейтинг: 0 / 0
Как правильно применить INNER JOIN под VFP98?
    #32371079
vl2000
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
>еще можно без inner join-а:
>SELECT B.GOROD, C.ULICA, A.DOM ;
>FROM ADR A, GOR B, UL C ;
>WHERE A.KOD_GOR=B.KOD AND A.KOD_UL=C.KOD

А если в таблице адреса будет ссылка NULL на код улицы в справочнике улиц?
Тогда этот адрес вообще не войдет в выборку?
...
Рейтинг: 0 / 0
Как правильно применить INNER JOIN под VFP98?
    #32371384
andrush
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Третий справочник должен быть связан с первым или вторым и затем аналогично
...
Рейтинг: 0 / 0
Как правильно применить INNER JOIN под VFP98?
    #32372004
vl2000
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
>andrush
извините, не понял к чему относится Ваша реплика.
Если к теме, поднятой neznajka , то там только два справочника- городов и улиц.
Если к вопросу, который потом задал я- "А вот как сделать то же самое, но для трёх справочников?", то в том то и дело, что он не связан ни с первым ни со вторым. Ситуация из энергетики: есть точки учета электроэнергии. Они содержатся в таблице ТУ (точки учета). Её расположение характеризуется тремя справочниками (в таблице ТУ есть 3 поля). 1.Подстанция. 2.Линия на Подстанции. 3.ТП (трансформатор понижающий) на линии.
Причем: она может иметь только 1-ую характеристику (только подстанция), 1-ую и 2-ую (подстанция и линия), 1, 2, и 3-ю.
Как в этом случае получить результирующий набор данных? Да, еще такой нюанс. Эти три справочника связаны и между собой. 3-ий со 2-м (я всегда могу выбрать ТП на Линии, 2-й с 1-м (могу выбрать Линии от Подстанции).
...
Рейтинг: 0 / 0
Как правильно применить INNER JOIN под VFP98?
    #32372053
andrush
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
>vl2000
Если 3 справочника (независимые друг от друга), то одним скл ни как.
А если как у тебя, то есть варианты:
1) SELECT ... ;
FROM table1 INNER JOIN sprav1 INNER JOIN sprav2 INNER JOIN sprav3 ;
ON sprav3.tp=sprav2.tp ;
ON sprav1.linia=sprav2.linia ;
ON sprav1.stanc=table1.stanc
INTO CURSOR cus1
выберет из table1 все записи с подстанциями у которых есть линии и ТП
2) Если надо выбрать все записи с подстанциями в независимости есть у них линии или нет, то
FROM table1 INNER JOIN sprav1 LEFT OUTER JOIN sprav2 INNER JOIN sprav3 ;
и т.д. и т.п.

sprav1 - справочник подстанций
sprav2 - справочник линий (tp - к какой относится подстанции)
sprav3 - справочник ТП (linia - к какой относится линии)
...
Рейтинг: 0 / 0
Как правильно применить INNER JOIN под VFP98?
    #32372178
vl2000
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
>andrush
Исходные данные:

*---------- это характеризует эл.сеть ---------------
sprav_podst.dbf && справочник подстанций
id_podst
name_podst
...
sprav_line.dbf && справочник линий от подстанции, id_line ссылка на родит. ПС
id_line
id_podst
name_line
...
sprav_tp.dbf && справочник ТП на линии, id_line ссылка на родит. линию
id_tp
id_line
name_tp
...
*----------------------------------

*----- а это точка учета, имеющая место в этой эл.сети ----
tu.dbf
id_tu
id_podst
id_line
id_tp
name_tu
...
*----------------------------------

В зависимости от типа точки учета, таблица TU может быть заполнена так (по полям):
1,1,1,1,'Кормоцех' && ТУ подключена через ПС, Линию и ТП
2,1,1,null,'Дойка' && ТУ подключена через ПС и Линию, (ТП нет)
3,1,null,null,'Зерноток' && ТУ подключена через ПС (Линии и ТП нет)

Задача: Получить данные из таблицы TU, подставив туда вместо кодов ПС, линии и ТП их названия. (UNION не применять)
...
Рейтинг: 0 / 0
Как правильно применить INNER JOIN под VFP98?
    #32372299
andrush
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ЛИРИКА - с токи зрения теории у тебя правильно сделаны таблицы. НО. Иногда лучше от нее отступить чуть-чуть. В данном случае - в tu.dbf лучше вместо кодов подставлять имена (но пользователь их должен выбирать из справчника)- особенно тогда, когда они не меняются или очень редко. Ручками или программой при необходимости можно их потом заменить

ПРОЗА.
Получить данные из таблицы TU, подставив туда вместо кодов ПС, линии и ТП их названия.

Где-то так

SELECT id_tu,name_tu,name_podst,NVL(name_line,SPACE(20)) AS name_line, ;
NVL(name_tp,SPACE(28)) AS name_tp ;
FROM tu INNER JOIN sprav_podst LEFT OUTER JOIN sprav_line ;
LEFT OUTER JOIN sprav_tp ;
ON sprav_tp.id_line=sprav_line.id_line ;
ON sprav_line=sprav_podst.id_podst ;
ON sprav_podst.id_podst=tu.id_podst ;
INTO CURSOR cus1

space(20) - вместо 20 длину поля name_line или ТАК SPACE(LEN(name_line))
space(28) - вместо 28 длину поля name_tp или ТАК SPACE(LEN(name_tp))
Это для случаев если первая выбранная запись имеет поле c NULL

Если несложно, то изменил бы tu.dbf :)
...
Рейтинг: 0 / 0
Как правильно применить INNER JOIN под VFP98?
    #32372381
andrush
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вдогонку. На некоторых наборах данных предыдущий запрос может давать неверные данные.
Попробый вот этот:
Код: plaintext
1.
2.
3.
4.
5.
6.
SELECT id_tu,name_tu,name_podst,NVL(name_line,SPACE( 20 )) AS name_line, NVL(name_tp,SPACE( 28 )) AS name_tp ; 
FROM sprav_tp  RIGHT OUTER JOIN tu INNER JOIN sprav_podst LEFT OUTER JOIN sprav_line ; 
   ON sprav_line.id_podst=sprav_podst.id_podst ; 
   ON sprav_podst.id_podst=tu.id_podst ; 
  ON tu.id_p=sprav_tp.id_p ; 
INTO CURSOR cus1
...
Рейтинг: 0 / 0
Как правильно применить INNER JOIN под VFP98?
    #32372513
vl2000
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
>andrush
Я думаю и последний SELECT не справится. Объясню почему.

...sprav_podst LEFT OUTER JOIN sprav_line ;
....
ON sprav_line.id_podst=sprav_podst.id_podst ;
......

Вы линию связываете с подстанцией по коду подстанции. Но от подстанции может отходить одна линия, а может и 20. В ТУ (точке учета) конкретно указан код этой линии. А в Вашем примере код линии из таблицы ТУ никак не учитывается. Какая же линия войдет в набор? Первая, последняя, все?
...
Рейтинг: 0 / 0
Как правильно применить INNER JOIN под VFP98?
    #32372515
vl2000
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
>andrush
т.к. приложение, которое я писал, имело тип файл-сервер, я не стал париться с этим Селектом, а просто подвязал к таблице TU.DBF (Точки Учета) через SET RELATION эти три справочника (там потом оказалось не три, а 4 или 5, еще код насел. пункта и т.п.). И, в связи с вышеизложенным, не стал хранить в TU.DBF названия из этих справочников.
Сейчас делаю попытки написать клиент-серверное приложение. Там Сет Релейшн не прокатит, вот и думаю, как это связывание сделать оптимальным способом. Похоже, есть несколько вариантов.
1.Несколько проходов (каждый проход связывает с одним из справочников)
2.Через ХП (которая по коду бдет находить название)
Других вариантов пока не знаю.
...
Рейтинг: 0 / 0
Как правильно применить INNER JOIN под VFP98?
    #32373138
user12
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
>еще можно без inner join-а:
>SELECT B.GOROD, C.ULICA, A.DOM ;
>FROM ADR A, GOR B, UL C ;
>WHERE A.KOD_GOR=B.KOD AND A.KOD_UL=C.KOD

А если в таблице адреса будет ссылка NULL на код улицы в справочнике улиц?
Тогда этот адрес вообще не войдет в выборку?_____________________________________________

А нельзя в where применить iif(isnull(A.KOD_UL),.T.,iif((A.KOD_UL=C.KOD ),.T.,.F.))

соответственно в SELECT iif(isnull(A.KOD_UL),"NULL",C.ULICA) as Улица,
...
Рейтинг: 0 / 0
Как правильно применить INNER JOIN под VFP98?
    #32374597
Igor Korolyov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Млин coolkenga давно уже дал верное решение а вы всё продолжаете какой-то ерундой маятся...
JOIN ... JOIN ... JOIN ... ON ... ON ... ON - это в 99% случаев будет неверный синтаксис (ибо без скобок и точной выверки порядка следования нереально составить последовательность ON-ов правильно)
А вот ежели писать JOIN ... ON ... JOIN ... ON и т.д. - то всё будет тип-топ - можно приклеить вплоть до 9-ти таблиц (ограничение фокса).
Причём неважно как именно они связаны - все с первой или поочерёдно друг с другом...
Т.е. A JOIN B ON B.Id = A.FKa JOIN C ON C.Id = A.FKc JOIN D ON D.ID = C.FKc ... и т.д. JOIN конечно могут быть и внешними.
Код: plaintext
iif(isnull(A.KOD_UL), "NULL" ,C.ULICA)

Решается через NVL() проще и красивее.
WBR, Igor
...
Рейтинг: 0 / 0
Как правильно применить INNER JOIN под VFP98?
    #32374797
coolkenga
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
>а что такое ?
>Решается через NVL() проще и красивее.

ЗЫ немного не в тему - coolkenga - это ОНА
...
Рейтинг: 0 / 0
Как правильно применить INNER JOIN под VFP98?
    #32375163
vl2000
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Извиняюсь, эта задача действительно решается последовательными
JOIN..ON
JOIN..ON
...
Рейтинг: 0 / 0
Как правильно применить INNER JOIN под VFP98?
    #32375842
Igor Korolyov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
coolkengaЗЫ немного не в тему - coolkenga - это ОНА
Упс, сорри :( Не знал...

WBR, Igor
...
Рейтинг: 0 / 0
Как правильно применить INNER JOIN под VFP98?
    #32376561
Ramil Mustafin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
coolkengaА разве условие по которому две таблицы соединяются (то, что после on) нужно не сразу после конкретного join-а
SELECT B.GOROD, C.ULICA, A.DOM FROM ADR A ;
INNER JOIN GOR B ;
ON A.KOD_GOR=B.KOD ;
INNER JOIN UL C ;
ON A.KOD_UL=C.KOD

________________________________
1) Что будет если A.KOD_UL=NULL ? ? vl2000Тогда этот адрес вообще не войдет в выборку?
2) Чем такой запрос (INNER JOIN) отличается от:
________________________________
coolkengaеще можно без inner join-а
SELECT B.GOROD, C.ULICA, A.DOM ;
FROM ADR A, GOR B, UL C ;
WHERE A.KOD_GOR=B.KOD AND A.KOD_UL=C.KOD

_________________________
...
Рейтинг: 0 / 0
Как правильно применить INNER JOIN под VFP98?
    #32376949
coolkenga
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
2 Igor Korolyov
так что же такое?
>Решается через NVL() проще и красивее

2 Ramil Mustafin
Ramil Mustafin 1) Что будет если A.KOD_UL=NULL ? ?
Тогда этот адрес вообще не войдет в выборку?
Тогда надо сделать вместо inner join - left join, главное чтобы код улицы не дублировался в справочнике улиц

Ramil Mustafin
2) Чем такой запрос (INNER JOIN) отличается от:
________________________________
coolkenga
еще можно без inner join-а
SELECT B.GOROD, C.ULICA, A.DOM ;
FROM ADR A, GOR B, UL C ;
WHERE A.KOD_GOR=B.KOD AND A.KOD_UL=C.KOD
Цитата (BOL):
In the SQL-92 standard, inner joins can be specified in either the FROM or WHERE clause. This is the only type of join that SQL-92 supports in the WHERE clause. Inner joins specified in the WHERE clause are known as old-style inner joins.
Т.е. проще говоря, MS SQL Books Online, говорят, что это старый стиль написания join-ов.
...
Рейтинг: 0 / 0
Как правильно применить INNER JOIN под VFP98?
    #32378985
Igor Korolyov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да плохо выразился... В общем если мы цепляемся по LEFT JOIN, то совершенно безразлично какое было значение поля внешнего ключа в основной таблице (левой т.е.) - если оно там было .NULL. то эта запись всё равно попадёт в выборку, и к ней привяжутся .NULL.-ы в качестве значений полей привязываемой таблицы (правой т.е.) и совершенно не нужно никаких ISNULL ни в ON ни в WHERE - достаточно NVL для "привязываемого" поля (поля из правой таблицы).
Т.е. в терминах приведенного примера - если код улицы в ADDR будет .NULL. то к нему привяжется куча .NULL.-ов, точно так-же, как если бы такого кода просто не было в справочнике улиц... Ну т.е. .NULL. в подобных ситуациях (LEFT JOIN) вполне таки обрабатывается стандартными средствами...
Теперь немного насчёт того что я критиковал:
user12А нельзя в where применить iif(isnull(A.KOD_UL),.T.,iif((A.KOD_UL=C.KOD ),.T.,.F.))
Нельзя! Почему - объяснять долго, но написав простейший пример можно убедится что это не будет работать... (для .NULL. в главной пройдёт RECCOUNT("привязываемой_таблицы") вхождений, да ещё и не с .NULL.-ами как должно, а с реальными записями привязываемой таблицы, что конечно неверно)
Да и вообще такие конструкции немного напрягают своей избыточностью - примерно как
Код: plaintext
IF (lBoolean = .T.)

А к чему было сказано
user12iif(isnull(A.KOD_UL),"NULL",C.ULICA)
Я вообще не понял... Если мы корректно привязываем A к С (LEFT JOIN-ом), то это будет
Код: plaintext
NVL(C.ULICA,PADR( "NULL - aka нет улицы в справочнике" , размер_поля_ULICA))

Надеюсь понятно изложил...
WBR, Igor
...
Рейтинг: 0 / 0
22 сообщений из 22, страница 1 из 1
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Как правильно применить INNER JOIN под VFP98?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]