powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Написала чушь в запросе. Помогите научиться
20 сообщений из 20, страница 1 из 1
Написала чушь в запросе. Помогите научиться
    #33286210
Лисонька
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Леди и джентельмены!
Искренне прошу прощения за свой очень простой вопрос. Пример:
Tab1: nId, cRegNomer (12)
Tab2: nId, cDelNomer (12)
Нужно выбрать те записи из Tab1, которые по Tab1.cRegNomer совпадают с Tab2.cDelNomer.
Пишу:
Код: plaintext
SELECT Tab1.nId, Tab1.cRegNomer FROM Tab1 HAVING Tab1.cRegNomer =Tab2.cDelNomer INTO CURSOR tmp
Или:
Код: plaintext
SELECT Tab1.nId, Tab1.cRegNomer FROM Tab1 WHERE Tab1.cRegNomer =Tab2.cDelNomer INTO CURSOR tmp
Получается ерунда. Значит, написала полную чушь.
Подскажите, что далаю не так.
Благодарю
...
Рейтинг: 0 / 0
Написала чушь в запросе. Помогите научиться
    #33286228
Станислав C.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЛисонькаЛеди и джентельмены!
Искренне прошу прощения за свой очень простой вопрос. Пример:
Tab1: nId, cRegNomer (12)
Tab2: nId, cDelNomer (12)
Нужно выбрать те записи из Tab1, которые по Tab1.cRegNomer совпадают с Tab2.cDelNomer.
Пишу:
Код: plaintext
SELECT Tab1.nId, Tab1.cRegNomer FROM Tab1 HAVING Tab1.cRegNomer =Tab2.cDelNomer INTO CURSOR tmp
Или:
Код: plaintext
SELECT Tab1.nId, Tab1.cRegNomer FROM Tab1 WHERE Tab1.cRegNomer =Tab2.cDelNomer INTO CURSOR tmp
Получается ерунда. Значит, написала полную чушь.
Подскажите, что далаю не так.
Благодарю
Если я понял правильно, то можно так:
Код: plaintext
1.
SELECT Tab1.nId, Tab1.cRegNomer FROM Tab1 WHERE Tab1.cRegNomer in (select Tab2.cDelNomer from Tab2) INTO CURSOR tmp
...
Рейтинг: 0 / 0
Написала чушь в запросе. Помогите научиться
    #33286246
Станислав C.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЛисонькаЛеди и джентельмены!
Искренне прошу прощения за свой очень простой вопрос. Пример:
Tab1: nId, cRegNomer (12)
Tab2: nId, cDelNomer (12)
Нужно выбрать те записи из Tab1, которые по Tab1.cRegNomer совпадают с Tab2.cDelNomer.
Пишу:
Код: plaintext
SELECT Tab1.nId, Tab1.cRegNomer FROM Tab1 HAVING Tab1.cRegNomer =Tab2.cDelNomer INTO CURSOR tmp
Или:
Код: plaintext
SELECT Tab1.nId, Tab1.cRegNomer FROM Tab1 WHERE Tab1.cRegNomer =Tab2.cDelNomer INTO CURSOR tmp
Получается ерунда. Значит, написала полную чушь.
Подскажите, что далаю не так.
Благодарю
Хотя, можно и так. Только подправить чуть-чуть:
Код: plaintext
SELECT Tab1.nId, Tab1.cRegNomer FROM Tab1, Tab2 WHERE Tab1.cRegNomer =Tab2.cDelNomer INTO CURSOR tmp
...
Рейтинг: 0 / 0
Написала чушь в запросе. Помогите научиться
    #33286438
AleksMed
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну и так можешь:
SELECT Tab1.nId, Tab1.cRegNomer FROM Tab1 INNER JOIN Tab2 ON Tab1.cRegNomer =Tab2.cDelNomer INTO CURSOR tmp
...
Рейтинг: 0 / 0
Написала чушь в запросе. Помогите научиться
    #33286521
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
На данном сайте есть книга

Понимание SQL (Understanding SQL)

Почитай там главу 8. Запрос многих таблиц как одной

Правда, там нет объединения по JOIN, но в остальном вполне можно использовать.
...
Рейтинг: 0 / 0
Написала чушь в запросе. Помогите научиться
    #33286566
Лисонька
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВладимирМНа данном сайте есть книга

Понимание SQL (Understanding SQL)

Почитай там главу 8. Запрос многих таблиц как одной

Правда, там нет объединения по JOIN, но в остальном вполне можно использовать.
Спасибо, эту книгу мне летом уже переслал один знакомый по e-mail, начала читать и забросила - некогда. Нужно начинать ее заново.
...
Рейтинг: 0 / 0
Написала чушь в запросе. Помогите научиться
    #33286671
Лисонька
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Так, джентельмены, позвольте доложить о моих результатах.
В Tab1 у меня около 20 000 записей, в Tab2 - более 82 000.

Код: plaintext
SELECT Tab1.nId, Tab1.cRegNomer FROM Tab1 WHERE Tab1.cRegNomer in (select Tab2.cDelNomer from Tab2) INTO CURSOR tmp
Отобрано 13 тыс. записей за 0,32 сек (правильность еще не проверяла).

Код: plaintext
SELECT Tab1.nId, Tab1.cRegNomer FROM Tab1, Tab2 WHERE Tab1.cRegNomer =Tab2.cDelNomer INTO CURSOR tmp
или
Код: plaintext
SELECT Tab1.nId, Tab1.cRegNomer FROM Tab1 INNER JOIN Tab2 ON Tab1.cRegNomer =Tab2.cDelNomer INTO CURSOR tmp
Компьютер мой задумался надолго, 2% запроса было выполнено им минут за 5, после чего вышло сообщение: File c:\.....\Temp\m4fk005q.tmp is too large.
М-да-а... Моих 8 свободных гигов на С явно оказалось маловато. Интересно было бы взглянуть, чего же он там понавыбирал? ;-)
...
Рейтинг: 0 / 0
Написала чушь в запросе. Помогите научиться
    #33286734
alex11100
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
бест регардз любителям
селектов на больших файловых таблицах

лисонька а ты еще по 10мбитной сетке
(вот и плюются делфисты и им подобные на фокс, когда
насмотрятся таких извращений) зато селекта, круто аж жуть
так держать!!!!

только что разговор на энту тему в фоксклабе был
ручками попроще и пошустрее будет


или в SQL все


во поизголялся- злой я, покусаю всех,

пойду чай с мурмурладом попью
...
Рейтинг: 0 / 0
Написала чушь в запросе. Помогите научиться
    #33286741
Фотография Hel!Riser
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
видима у тебя очень много полей с пустым (или одинаковым) значением cRegNomer и cDelNomer. Отсюдова получаеца, што во 2 и 3 случаях декартово произведение выходит за рамку свободного места на винте
а в первом - то множество одинаковых значений не эту образует матрицу..
ЗЫ видима ответил непонятна
...
Рейтинг: 0 / 0
Написала чушь в запросе. Помогите научиться
    #33286747
Фотография Hel!Riser
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 alex11100
извини конешна, но ты как в лужу п:ернул со своим трейдом
...
Рейтинг: 0 / 0
Написала чушь в запросе. Помогите научиться
    #33286767
Лисонька
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alex11100бест регардз любителям
селектов на больших файловых таблицах

лисонька а ты еще по 10мбитной сетке
(вот и плюются делфисты и им подобные на фокс, когда
насмотрятся таких извращений) зато селекта, круто аж жуть
так держать!!!!

только что разговор на энту тему в фоксклабе был
ручками попроще и пошустрее будет


или в SQL все


во поизголялся- злой я, покусаю всех,

пойду чай с мурмурладом попью
Эта роль ругательная и прошу ко мне ее не применять! Или сочувственная? ;-))))))
Короче говоря, лучше бы я пошла через SCAN... LOCATE (SEEK)... IF FOUND()=.T. ... ENDSCAN и не мучала себя в данном случае запросом?
Проверила получившуюся выборку. В нее помимо нужного попали еще записи с пустым значением Tab1.cRegNomer.
Приписала еще тогда условие AND Tab1.cRegNomer# ' '. Пуснтые значения из выборки исчезли, но зато попало несколько записей с длиной Tab1.cRegNomer в 1 символ (без концевых пробелов).
Почему так получается?
...
Рейтинг: 0 / 0
Написала чушь в запросе. Помогите научиться
    #33286778
Лисонька
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Hel!Riserвидима у тебя очень много полей с пустым (или одинаковым) значением cRegNomer и cDelNomer. Отсюдова получаеца, што во 2 и 3 случаях декартово произведение выходит за рамку свободного места на винте
а в первом - то множество одинаковых значений не эту образует матрицу..
ЗЫ видима ответил непонятна
Точно!
Соотношение пустых значений к непустым 10 : 1.
Декартово произведение? Что-то проходили лет 8 назад в институте. Или нет? :-)
...
Рейтинг: 0 / 0
Написала чушь в запросе. Помогите научиться
    #33286784
Фотография Hel!Riser
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
[quot Лисонька
Приписала еще тогда условие AND Tab1.cRegNomer# ' '. Пуснтые значения из выборки исчезли, но зато попало несколько записей с длиной Tab1.cRegNomer в 1 символ (без концевых пробелов).
Почему так получается?[/quot]
AND !EMPTY(Tab1.cRegNomer)
...
Рейтинг: 0 / 0
Написала чушь в запросе. Помогите научиться
    #33286791
Фотография Hel!Riser
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЛисонькаЧто-то проходили лет 8 назад в институте. Или нет?
ага. уже слово больно красивое. Решил выпиндрица
...
Рейтинг: 0 / 0
Написала чушь в запросе. Помогите научиться
    #33286864
Лисонька
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да, кое-что вспомнила про декартово произведение. Что-то про все возможные табличные строки, сцепленные там еще с чем-то. Повторю слова Кэролловской Алисы: "Как все это сложно и непонятно!"
...
Рейтинг: 0 / 0
Написала чушь в запросе. Помогите научиться
    #33286889
GoshaS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SELECT nId, cRegNomer FROM Tab1 WHERE Tab1.cRegNomer in (select distinct cDelNomer from Tab2) INTO CURSOR tmp

IMHO
Посмотри
? SET('delete')
если включено, тогда может помочь установка индекса по DELETE
На относительно больших объемах помогает. У меня запрос из 4-ех таблиц, два справочника и две таблицы больше 1мл. записей, при индексировании по "DEL" в таблицах данных, запрос стал работать быстрее процентов на 40.

Опять же, если выставлял индекс по "DEL" в таблицах-справочников, тогда запрос выполнялся медленней.
...
Рейтинг: 0 / 0
Написала чушь в запросе. Помогите научиться
    #33286928
Urri
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Лисонька! А может, тебе надо всего-то:
Код: plaintext
1.
2.
local m.x
m.x = Tab2.cDelNomer
SELECT Tab1.nId, Tab1.cRegNomer FROM Tab1 WHERE Tab1.cRegNomer = m.x INTO CURSOR tmp
?
А то наворотили тут, понимаешь ;-)
...
Рейтинг: 0 / 0
Написала чушь в запросе. Помогите научиться
    #33286947
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Тренироваться лучше "на кошечках". В смысле, сделать тестовые курсоры и смотреть что получиться. В общем случае IN и INNER JOIN вовсе не равнозначны.

Вот пример для опытов.

Код: 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.
25.
26.
27.
create cursor tab1 (nId I, cRegNomer C( 12 ))
index on cRegNomer tag cRegNomer
insert into tab1 (nId, cRegNomer) values ( 1 , "Первый")
insert into tab1 (nId, cRegNomer) values ( 2 , "Второй")
insert into tab1 (nId, cRegNomer) values ( 3 , "")		&& пустое значение

* Во второй таблице каждое значение удваиваю
create cursor tab2 (nId I, cDelNomer C( 12 ))
index on cDelNomer tag cDelNomer 
insert into tab2 (nId, cDelNomer) values ( 1 , "Первый")
insert into tab2 (nId, cDelNomer) values ( 1 , "Первый")
insert into tab2 (nId, cDelNomer) values ( 2 , "Второй")
insert into tab2 (nId, cDelNomer) values ( 2 , "Второй")
insert into tab2 (nId, cDelNomer) values ( 3 , "")		&& пустое значение
insert into tab2 (nId, cDelNomer) values ( 3 , "")		&& пустое значение

* Используем IN
SELECT Tab1.nId, Tab1.cRegNomer ;
FROM Tab1 ;
WHERE tab1.cRegNomer<>SPACE( 12 ) ;
	AND tab1.cRegNomer IN (SELECT tab2.cDelNomer FROM tab2)

* Используем INNER JOIN	
SELECT Tab1.nId, Tab1.cRegNomer ;
FROM Tab1 ;
INNER JOIN tab2 ON tab1.cRegNomer = tab2.cDelNomer ;
WHERE tab1.cRegNomer<>SPACE( 12 ) 

Некоторые пояснения.

Я использую конструкцию WHERE tab1.cRegNomer<>SPACE(12), а не !EMPTY(tab1.cRegNomer), потому, что SPACE(12) будет использовать существующий индекс (т.е. запрос оптимизируется или ускоряется), а EMPTY() - не будет.

Как видно по результату, при использовании IN будет отбираться не более одной записи из таблицы tab1 на каждую найденную запись из таблицы tab2, а при использовании INNER JOIN получишь произведение найденных записей d tab1 и tab2.
...
Рейтинг: 0 / 0
Написала чушь в запросе. Помогите научиться
    #33287004
Igor Korolyov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Hi Лисонька!

1) Если в tab2 будет 10 записей с одним и тем-же кодом, и в tab1 будет 10 записей с этим кодом - то при запросе типа
Код: plaintext
SELECT Tab1.* FROM Tab1, Tab2  WHERE Tab1.cRegNomer =Tab2.cDelNomer INTO CURSOR tmp
в выборку попадут не 10 "подходящих", а 100 - т.е. каждая нужная запись повторится 10 раз. соответственно если будет по 100 "дублей", то получим уже 10000 записей в результате!
Эта неприятность не случилась бы, если бы cDelNomer в tab2 был уникален (т.е. одно значение не повторялось в нескольких записях).
Но конечно лучше запрос с IN (SELECT ... ) использовать.
2) "Задумался" он и упал в конце концов, потому что у тебя чересчур много дублей было в таблице. В самом "страшном" случае - если бы ВСЕ записи обеих таблиц содержали одно и то-же значение в полях связи, в результате твоего запроса должна была-бы образоваться выборка размером примерно в 26 Гигабайт (20000*82000*17 - где 17 это размер одной записи новой выборки - я предполагаю что nID имеет тип Integer - т.е. 4 байта+12 байт+1 на признак удаления). Фокс не может производить выборок размером более 2 Гб (ограничение на размер dbf действует и на "временные" курсоры). Для превышения этого лимита в принципе достаточно чтобы в первой и второй таблице было хотя-бы по 12000 записей с идентичным значением полей связи (например ПУСТЫМИ полями cRegNomer и cDelNomer)
3) Сравнение Tab1.cRegNomer # " " - не совсем корректно - если поле имеет размер C(12) то и выражение для сравнения должно быть размером 12 символов, ИЛИ должна действовать установка SET ANSI ON (тогда фокс сам дополнит более короткую строку до длинны второй строки), ИЛИ нужно использовать сравнение == что аналогично "местному" применению SET ANSI ON (т.е. тогда условие будет выглядеть как [src]!(Tab1.cRegNomer == " ")[src]). В целом ряде случаев может помочь и банальное !EMPTY() - главное не забывать, что "пустое" это и пробел и TAB и перевод строки... Если поле не "бинарное" то обычно это не критично.
Указанное сравнение же даст .T. и в случае когда cRegNomer = " 123" и для cRegNomer = " ABC"... И вообще всех тех где только ПЕРВЫЙ символ поля есть пробел.
4) Чтобы получать пользу (и удовольствие) от SQL запросов необходимо подумать про оптимизатор - обеспечить его нужными индексами. В данном случае - нужны индексы по этим символьным полям.

Posted via ActualForum NNTP Server 1.3
...
Рейтинг: 0 / 0
Написала чушь в запросе. Помогите научиться
    #33287027
Лисонька
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Искренняя благодарность всем. Надо сегодня вечером поэксперементировать с этими таблицами и всеми вариантами запросов, с индексами и пустыми полями.
...
Рейтинг: 0 / 0
20 сообщений из 20, страница 1 из 1
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Написала чушь в запросе. Помогите научиться
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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