如何在 FoxPro 中使用 SET FILTER TO 将结果限制为另一个游标中的匹配记录

发布于 2024-12-10 14:10:49 字数 727 浏览 1 评论 0原文

假设,我有一个包含数据记录的游标,在 csrData 中具有标识外键:

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

并且在单独的游标中包含外部 ID 列表 csrMatches

|  Match_Foreign_ID  |  
|  1                 |  
|  3                 |  

是否存在 SET我可以针对 csrData 发出 FILTER TO 命令来获取:

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

我知道这可以使用 SQL 查询来实现,但我使用的报告框架限制我SET FILTER TO声明。 INLIST() 函数的工作原理类似,但我想对一组未知大小进行过滤。

Say, I've got a cursor with data records, with an identifying foreign key in csrData:

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

And a list of foreign IDs in a separate cursor csrMatches:

|  Match_Foreign_ID  |  
|  1                 |  
|  3                 |  

Is there a SET FILTER TO command I can issue against csrData to get:

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

I know this can be achieved using a SQL query, but the reporting framework I'm using limits me to SET FILTER TO statements. The INLIST() function works similarly, but I'd like to do filtering against a set of unknown size.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

煞人兵器 2024-12-17 14:10:49

您可以创建一个过滤条件,在 csrMatches 中查找给定的 csrData.Foreign_ID,如果找到则返回 true,否则返回 false。

首先,在 csrMatches 中的 Match_Foreign_ID 字段上创建索引。然后,创建一个过滤器,使用 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() 只是使用索引来检查是否找到键,并且不移动活动记录指针。

You can create a filter condition that will look up a given csrData.Foreign_ID in csrMatches and return true if it's found, false otherwise.

First, create an index on the Match_Foreign_ID field in csrMatches. Then, create a filter that uses indexseek() to test each Foreign_ID for inclusion in csrMatches.

select csrMatches
index on Match_Foreign_ID tag Foreign_ID

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

Using indexseek() is slightly faster than seek() because indexseek() simply uses the index to check if the key is found, and does not move the active record pointer.

七颜 2024-12-17 14:10:49

如果您在每个“游标”上都有一个索引,则可以通过设置关系、设置过滤器来完成...

如果您通过 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" )

这种方法的另一个优点是,您还可以过滤另一个表中列的值...如果您需要的话。例如,如果您将销售链接到客户表,并希望根据特定州或地区的客户进行显示。当然,所有销售都将与客户相关联,但您可以通过以下方式应用过滤器

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" )

If you have an index on each "cursor", you could do it via set relation, set filter...

If you created the cursors via SELECT ... INTO CURSOR csrData, be sure to add the keyword "READWRITE" to allow a read-writable cursor that you can build index tags on..

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

same with csrMatches -- READWRITE.

Once created, do the following...

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" )

since the data is related INTO the other matches table, whenever the record pointer moves from one row to the other, it tries to find a match for you in the "related" cursor (or table). If it can't find one, that other cursor, it moves the other cursor to EOF() (end of file). So now, you can set filter to NOT EOF( "csrMatches" )

One additional advantage of this approach, is you can also filter on VALUES of columns IN the other table too... if you ever needed to. Such as if you were linking sales to customers table and wanted to show based on a customer's based on certain state or region. Of course, all sales would be associated to a customer, but you could apply the filter via

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" )
哥,最终变帅啦 2024-12-17 14:10:49

您可以使用 select 语句将这两个游标连接在一起。

SELECT * FROM csrData INNER JOIN csrMatches ON ID = Match_Foreign_ID INTO CURSOR 结果 NOFILTER

You could join these two cursors together using a select statement.

SELECT * FROM csrData INNER JOIN csrMatches ON ID = Match_Foreign_ID INTO CURSOR cresults NOFILTER

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文