powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Как выбрать записи одной таблицы отсутствующие в другой?
25 сообщений из 31, страница 1 из 2
Как выбрать записи одной таблицы отсутствующие в другой?
    #33179720
S866
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Уважаемый ALL
Есть две таблицы - с одинаковым полем идентификатором ID.
из первой таблицы надо выбрать записи те ID которых отсутствует в другой таблице. Сделал ручками в цикле - но очень хочется одной строчкой через SELECT (у селекта есть операнд in - по вхождению а тут как раз надо наоборот).
Помогите!!!
...
Рейтинг: 0 / 0
Как выбрать записи одной таблицы отсутствующие в другой?
    #33179728
AleksMed
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NOT IN
...
Рейтинг: 0 / 0
Как выбрать записи одной таблицы отсутствующие в другой?
    #33179739
AleksMed
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Или NOT EXISTS
...
Рейтинг: 0 / 0
Как выбрать записи одной таблицы отсутствующие в другой?
    #33179786
S866
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо - что то не сообразил что можно так синтаксис писать у Selectа
Буду пробовать
...
Рейтинг: 0 / 0
Как выбрать записи одной таблицы отсутствующие в другой?
    #33180104
S866
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как не кручу получается не совсем то что надо
- если операнд not in ставить в условии where - то исключается только текущая запись второй таблицы
- если операнд not in ставить в joint condition - то в зависимости от типа join получается такая фигня что заголову берешся.

а NOT EXISTS - что то я в фоксе не нашел
...
Рейтинг: 0 / 0
Как выбрать записи одной таблицы отсутствующие в другой?
    #33180117
AleksMed
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
select a.* from Table1 a where a.ID not in(select b.ID from Table2 b where b.ID=a.ID)
...
Рейтинг: 0 / 0
Как выбрать записи одной таблицы отсутствующие в другой?
    #33180148
S866
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо AleksMed - Это то что доктор прописал.
Тукую конструкцию мне туговато придумать было.
...
Рейтинг: 0 / 0
Как выбрать записи одной таблицы отсутствующие в другой?
    #33180166
S866
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо AleksMed - Это то что доктор прописал.
Тукую конструкцию мне туговато придумать было.
...
Рейтинг: 0 / 0
Как выбрать записи одной таблицы отсутствующие в другой?
    #33181512
Igor Korolyov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Hi AleksMed!

В данном случае WHERE в подзапросе не нужен :)
Это ты видимо из NOT EXISTS случайно загрёб :)

Posted via ActualForum NNTP Server 1.2
...
Рейтинг: 0 / 0
Как выбрать записи одной таблицы отсутствующие в другой?
    #33181535
Urri
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Igor Korolyov
Hi AleksMed!

В данном случае WHERE в подзапросе не нужен :)
Это ты видимо из NOT EXISTS случайно загрёб :)

Posted via ActualForum NNTP Server 1.2Привет, Игорь!
Наверное, в последних версиях VFP действительно не нужен - оптимизация запросов значительно продвинутей стала. В VFP9:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
CREATE CURSOR c1 (nn n( 6 ))
INDEX on nn TAG nn
CREATE CURSOR c2 (nn n( 6 ))
INDEX on nn TAG nn
FOR i =  1  TO  100000 
  INSERT INTO c1 VALUES (i)
  INSERT INTO c2 VALUES ( 100000 + 1 -i)
endfor
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
x=SECONDS()
select c1.* from c1 where c1.nn in (select c2.nn from c2 where c2.nn=c1.nn) INTO CURSOR cr
?SECONDS()-x
* Результат  1 . 093 
x=SECONDS()
select c1.* from c1 where c1.nn in (select c2.nn from c2) INTO CURSOR cr
?SECONDS()-x
* Результат  0 . 472 
Да только вот припоминаю, что в FPD дело обстояло совсем даже наоборот: без такого where работало долго, а с ним - быстро. Отсюда вывод: наличие where надо тестировать под используемую версию.
...
Рейтинг: 0 / 0
Как выбрать записи одной таблицы отсутствующие в другой?
    #33181584
Urri
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот результаты для FPD:
С Where 0.511 секунд,
без - 0.566 секунд.
...
Рейтинг: 0 / 0
Как выбрать записи одной таблицы отсутствующие в другой?
    #33181965
S866
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Здравствуйте!

К Urri - разве в Досовом Фоксе можно Select из Selecta вызывать ?
мне кажется вложенные селеkты с 7 визуал фокса появились.

к AlexMed & Igor Korolyov - интересен механизм работы вложенного селекта - он получается вызывается из внешнего селекта N раз где N - Количество записей в исходных таблицах ?
Хотя по приведенным цифрам - всеравно работает очень быстро.
Мне же необходимо было обработать таблицы порядка 100 записей в каждой.
Так что такая конструкция как вы предложили - наиболее красиво вписывается в код программы. - не то что я сторонник красивого кода - просто когда это надо в разных местах программы писать - проще 1 строчку вместо целого блока кода.
...
Рейтинг: 0 / 0
Как выбрать записи одной таблицы отсутствующие в другой?
    #33181981
Станислав C.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
S866Здравствуйте!

К Urri - разве в Досовом Фоксе можно Select из Selecta вызывать ?
мне кажется вложенные селеkты с 7 визуал фокса появились.


Можно! 5 лет работал на FPD 2.6 и этим пользовался... И в Helpе этот прием описан...
Только, помнится мне, что это (Select-SQL) было единственное место, где можно было использовать подзапросы... В других командах SQL в FPD такое не допускалось...
...
Рейтинг: 0 / 0
Как выбрать записи одной таблицы отсутствующие в другой?
    #33182156
Urri
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
S866К Urri - разве в Досовом Фоксе можно Select из Selecta вызывать ?
мне кажется вложенные селеkты с 7 визуал фокса появились.В конструкциях SELECT ... WHERE ... IN (SELECT...) и SELECT ... WHERE EXISTS (SELECT...) - можно.
...
Рейтинг: 0 / 0
Как выбрать записи одной таблицы отсутствующие в другой?
    #33182163
S866
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да все точно - у меня в 2.5 - тоже описано. Просто я селекты использовать с VFP 5 начал - там так в Хелпе не заморачиваются. к досовому фоксу справку делали более качественно. И переводили на русский тоже отлично.

Не знаете где бы Help под 8-ку или 9-ку найти русский?
...
Рейтинг: 0 / 0
Как выбрать записи одной таблицы отсутствующие в другой?
    #33182189
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
S866Не знаете где бы Help под 8-ку или 9-ку найти русский?

Проект - Русский HELP к Visual FoxPro
...
Рейтинг: 0 / 0
Как выбрать записи одной таблицы отсутствующие в другой?
    #33182548
S866
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо!
...
Рейтинг: 0 / 0
Как выбрать записи одной таблицы отсутствующие в другой?
    #33182619
Soplik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Можно и без вложенных селектов:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
LOCAL x
CREATE CURSOR c1 (nn n( 6 ))
INDEX on nn TAG nn
CREATE CURSOR c2 (nn n( 6 ))
INDEX on nn TAG nn
FOR i =  1  TO  100000 
  INSERT INTO c1 VALUES (i)
  INSERT INTO c2 VALUES (i+ 10 )
ENDFOR

x=SECONDS() 
SELECT c1.nn FROM c1 ;
WHERE NOT SEEK(nn,"c2","nn") ;
INTO CURSOR cr
?SECONDS()-x 
...
Рейтинг: 0 / 0
Как выбрать записи одной таблицы отсутствующие в другой?
    #33182668
AleksMed
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Igor Korolyov
Hi AleksMed!

В данном случае WHERE в подзапросе не нужен :)
Это ты видимо из NOT EXISTS случайно загрёб :)

Posted via ActualForum NNTP Server 1.2

Да в запаре еще и не то напишешь.
...
Рейтинг: 0 / 0
Как выбрать записи одной таблицы отсутствующие в другой?
    #33182996
S866
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Запустил код

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
LOCAL x
CREATE CURSOR c1 (nn n( 6 ))
INDEX on nn TAG nn
CREATE CURSOR c2 (nn n( 6 ))
INDEX on nn TAG nn
FOR i =  1  TO  100000 
  INSERT INTO c1 VALUES (i)
  INSERT INTO c2 VALUES (i+ 10 )
ENDFOR
&& вариант  1 
x=SECONDS()
select c1.* from c1 where c1.nn NOT in (select c2.nn from c2) INTO CURSOR cr
?'вариант 1'+STR(SECONDS()-x, 13 , 6 )

&& вариант  2 
x=SECONDS() 
SELECT c1.nn FROM c1 ;
WHERE NOT SEEK(nn,"c2","nn") ;
INTO CURSOR cr
?'вариант 2'+STR(SECONDS()-x, 13 , 6 )
 
&& вариант  3 
x=SECONDS()
select c1.* from c1 where c1.nn NOT in (select c2.nn from c2 where c2.nn=c1.nn) INTO CURSOR cr
?'вариант 3'+STR(SECONDS()-x, 13 , 6 )

результаты
Вар 1 = 0.352
Вар 2 = 0.621
Вар 3 = 0.781

Быстрее всего Вариант URRI

Спасибо всем за отклик
Тему наверно можно закрывать?
...
Рейтинг: 0 / 0
Как выбрать записи одной таблицы отсутствующие в другой?
    #33183853
Igor Korolyov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Hi Urri!

Ну оптимизатор вещь тонкая :) Просто сама суть подзапроса после IN - это
выбрать некоторый список, и потом по нему фильтровать - это
НЕкоррелированный подзапрос. А если добавить к нему условие связи с
"внешней" таблицей - мы получим коррелированный подзапрос - он будет на
каждой итерации выбирать всего 1 или 0 записей (логически, на самом деле не
совсем так о чём далее.) т.е. по сути не будет отличаться от условия с
EXISTS - просто вместо проверки "есть запись" будет выполняться "пустая"
проверка "a.id=b.id" - в которой значение имеет не собсвтенно ЧТО
сравнивается (это сравнение уже в WHERE прошло), а сам факт - если ли справа
хоть что-то или нету :)

2 S866
По поводу оптимизатора на forum.foxclub.ru немного говорил Алексей Цингауз -
оказывается даже коррелированные подзапросы в фоксе НЕ "выполняются N раз
для N записей основного запроса" а преобразуются в особого рода
"соединение"...

Posted via ActualForum NNTP Server 1.2
...
Рейтинг: 0 / 0
Как выбрать записи одной таблицы отсутствующие в другой?
    #33193100
AB_________1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
В VFP6 можно было использовать (в более старших версиях не работает):

Код: plaintext
1.
2.
3.
4.
5.
6.
&& вариант  4 
x=SECONDS()
select c1.* ;
  from c1 Left Join c2 on (c1.nn = c2.nn);
  where (c1.nn<>c2.nn) INTO CURSOR cr
?'вариант 4'+STR(SECONDS()-x, 13 , 6 )

Код: plaintext
1.
2.
3.
4.
У меня получилось:
вариант 1    0.23000
вариант 2    0.37100
вариант 3    0.43100
вариант 4    0.22000
...
Рейтинг: 0 / 0
Как выбрать записи одной таблицы отсутствующие в другой?
    #33195411
Igor Korolyov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Hi AB!

> В VFP6 можно было использовать (в более старших версиях не работает):

И это правильно.
Потому что это некорректный запрос - сравнение c1.nn#c2.nn в случае
отсутствия записи в с2 эквивалентно сравнению c1.nn#.NULL. которое ДОЛЖНО
отсекать записи,т.к. оно НЕ является .T.
К сожалению обработка NULL значений в таком случае (с внешними соединениями)
вплоть до VFP9 работает некорректно (однако с каждой новой версией всё лучше
и лучше, как это ни странно :) )
Корректное условие (которое позволит получить правильный результат в VFP8 и
старше) выглядит так:
.... where (c1.nn<>c2.nn) IS NULL ...
Однако на самом деле можно использовать более простое условие (опять таки
корректно оно будет работать лишь в VFP8 и старше)
.... where c2.nn IS NULL ...

Результаты у меня выглядят несколько иначе - выигрывает всегда первый
вариант, твой модифицированный вариант идёт вторым (даже если учитывать
некорректную работу под VFP7), затем идёт 2 и наконец 3.

VFP9
вариант 1 0,550
вариант 2 1,082
вариант 3 1,262
вариант 4 0,751

VFP8SP1
вариант 1 0,571
вариант 2 0,971
вариант 3 1,212
вариант 4 0,681

VFP7SP1
вариант 1 0,461
вариант 2 1,021
вариант 3 1,302
вариант 4 0,551

Вариант
select c1.* from c1 where NOT EXIST (select * from c2 where c2.nn=c1.nn)
INTO CURSOR cr
отрабатывает примерно так-же как и вариант 1 (и с корректностью результата
проблем тоже нет).

Результаты могут отличаться, если использовать для теста не курсор, а
реальные таблицы - уже хотя-бы потому что разные версии фокса по разному
строят индексы (VFP7 самые большие делает :) ). Также может влиять то, как
создан индекс - ДО заполнения или ПОСЛЕ заполнения таблиц.

Posted via ActualForum NNTP Server 1.2
...
Рейтинг: 0 / 0
Как выбрать записи одной таблицы отсутствующие в другой?
    #33196162
Crispy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Hi, Igor Korolyov !

Что интересно - результаты тестирования одного и того же варианта статистически - могут отличаться друг от друга! Легко проверить - выполнив подряд раз 10 одно и тоже действие. Различия могут достигать нескольких раз. Видимо влияет и фрагментированность диска, и выполнение Windows каких-то теневых или других процессов на данный момент, фрагментированность памяти и т.п. Обычно самое медленное выполнение - первое. Потом - все нужное уже в памяти, идет быстрее.
Поэтому, для лучшей достоверности, наверное, имеет смысл делать измерения в цикле, скажем, до 100, причем после каждого выполнения выгружать все "подвешенное", приводя в начальное состояние.
...
Рейтинг: 0 / 0
Как выбрать записи одной таблицы отсутствующие в другой?
    #33198063
Maltsev Max
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Еще можно так:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
&& вариант  5 
x=SECONDS()
select c1.* from c1;
Left JOIN c2 ON c2.nn=c1.nn;
where IsNull(c2.nn) INTO CURSOR cr
?'вариант 5'+STR(SECONDS()-x, 13 , 6 )


У меня получилось:
вариант 1 0.406000
вариант 2 0.610000
вариант 3 0.812000
вариант 4 0.453000
вариант 5 0.438000
...
Рейтинг: 0 / 0
25 сообщений из 31, страница 1 из 2
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Как выбрать записи одной таблицы отсутствующие в другой?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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