Как использовать SET FILTER TO в FoxPro, чтобы ограничить результаты соответствующими записями в другом курсоре - PullRequest
0 голосов
/ 18 октября 2011

Скажем, у меня есть курсор с записями данных с идентифицирующим внешним ключом в csrData:

|  ID  |  Foreign_ID  |  
|  1   |  1           |  
|  2   |  1           |  
|  3   |  2           |  
|  4   |  2           |  
|  5   |  2           |  
|  6   |  3           |  

И список иностранных идентификаторов в отдельном курсоре csrMatches:

|  Match_Foreign_ID  |  
|  1                 |  
|  3                 |  

Есть ли команда SET FILTER TO, которую я могу выполнить для csrData, чтобы получить:

|  ID  |  Foreign_ID  |  
|  1   |  1           |  
|  2   |  1           |  
|  6   |  3           |  

Я знаю, что этого можно достичь с помощью SQL-запроса, но используемая мной структура отчетности ограничивает меня до SET FILTER TO утверждениями. Функция INLIST() работает аналогично, но я бы хотел выполнить фильтрацию по набору неизвестного размера.

Ответы [ 3 ]

2 голосов
/ 18 октября 2011

Вы можете создать условие фильтра, которое будет искать заданный csrData.Foreign_ID в csrMatches и возвращать true, если оно найдено, в противном случае - false.

Сначала создайте индекс в поле Match_Foreign_ID вcsrMatches.Затем создайте фильтр, который использует indexseek() для проверки каждого Foreign_ID на включение в csrMatches.

select csrMatches
index on Match_Foreign_ID tag Foreign_ID

select csrData
set filter to indexseek(csrData.Foreign_ID, .f., "csrMatches", "Foreign_ID")

Использование indexseek() немного быстрее, чем seek() потому что indexseek() просто использует индекс для проверки, найден ли ключ, и не перемещает указатель активной записи.

2 голосов
/ 18 октября 2011

Если у вас есть индекс для каждого «курсора», вы можете сделать это с помощью набора отношений, установить фильтр ...

Если вы создали курсоры с помощью SELECT ... INTO CURSOR csrData, обязательнодобавьте ключевое слово «READWRITE», чтобы разрешить доступный для записи курсор, на котором вы можете создавать индексные теги ..

select ... from ... where ... into cursor csrData READWRITE

то же самое с csrMatches - READWRITE.

После создания выполните следующие действия....

select csrMatches
index on Match_Foreign_ID tag Foreign_ID

select csrData
set relation to Foreign_ID into csrMatches

set filter to NOT EOF( "csrMatches" )

, поскольку данные связаны с другой таблицей совпадений, всякий раз, когда указатель записи перемещается из одной строки в другую, он пытается найти совпадение для вас в «связанном» курсоре (или стол).Если он не может найти один, этот другой курсор, он перемещает другой курсор в EOF () (конец файла).Итак, теперь вы можете установить фильтр на NOT EOF ("csrMatches")

Еще одно преимущество этого подхода заключается в том, что вы также можете фильтровать значения VALUES столбцов в другой таблице ... если вам когда-либо понадобилось,Например, если вы связывали данные о продажах с таблицей клиентов и хотели бы показать их на основе данных о клиенте в определенном штате или регионе.Конечно, все продажи будут связаны с клиентом, но вы можете применить фильтр через

select customers
set index to customerID

select SalesSample
set relation to customerID into customers

set filter for not eof( "Customers" ) and inlist( Customers.State, "NY, "PA", "MA" )
0 голосов
/ 16 декабря 2011

Вы можете объединить эти два курсора, используя оператор выбора.

SELECT * FROM csrData INNER JOIN csrMatches ON ID = Match_Foreign_ID INTO CURSOR работает с NOFILTER

...