Yes, welcome here.
There are many ways to skin a cat, so I'll add some variants.
Again the SQL way I'd rather do a left join and filter for no join:
Code:
SELECT invoice.in_inv_num FROM invoice iv;
LEFT JOIN invoiceDetail ivd ON iv.in_inv_num = ivd.id_inv_num;
WHERE ivd.id_inv_num IS NULL
This works through the nature of the left OUTER join to even add invoice rows on the left result side, if there is no invoiceDetail and instead of invoiceDetail columns add NULLs on the right result side. Therefore that WHERE is finding all non matches, exactly what you need.
Also the xBase approach could be done by checking EOF, when no row is found in invoiceDetails it means the relation will put the pointer in invoiceDetails to EOF (end of file):
Code:
USE Invoice in 0
USE InvoiceDetail in 0 ORDER id_inv_num
SELECT Invoice
SET RELATION TO id_inv_num INTO InvoiceDetail
BROWSE FOR EOF("InvoiceDetail")
All the code of me and JRB-Bldr would need or profit of indexes on the data. The secondary examples both assume certain index naming conventions not necessarily true, namely index tag name is identical to field name. The situation could be, the indexes exist, but are differently named or the indexes don't exist at all.
If you open tables in the table designer via MODIFY STRUCTURE (for example) you can see what indexes exist and eventually add some.
I'd go for the SQL variants, as SQL is a more general solution you may later also apply to MSSQL, MySQL and other databases. But what version of Foxpro is at hand for you?
Bye, Olaf.