Search code examples
sqlvisual-foxprofoxpro

Foxpro query to select a single record from each group


I am hoping to find a simple SQL solution to my question. I have searched for one, but have been unable to find anything that works for my situation.

I have a .dbf with client data, consisting of customer names, addresses and other information, to be used for a commercial mailing. Each record gets assigned to a group, or package, and each package will be mailed separately. Occasionally I need to pull out records from one or more groups, into a new dbf, to set up as client seeds, updating them with new names and addresses, so the client will get a copy of the letter in the mail. Typically it's only one or two groups, in which case I can simply pick the first record, or find two sequential records that belong to different groups. Currently I have a file with 6 groups, and I need a single record from each group.

Basically I want to do the following, but I know this command doesn't work.

select * from customer group by package into table seeds

One way of doing this would be to do the following:

use customer
index on package unique
set order to package
copy to seeds
delete tag all

Alternatively, I could copy one record from each group into separate files, then append them to a single seed file.

Is there a way to get a single record from each group using a sql select statement?


Solution

  • Select * From Customers ;
        where CustomerId In ;
          (Select Min(CustomerId) From Customers Group By package) ;
        order By package ;
        into Cursor crsResult ;
        nofilter
    

    This code assumes that you want to select one customer from each package group, regardless of which one that is (selecting the one with the min(customerId)) - ( it could be max(CustomerId) or, using longer SQL, pick top 1 from each group -like you did with unique- or, again with a much longer SQL, order in a particular order and pick Nth per group, or a random pick from each group if you need a randomization on selects).

    Note: This is a hack that I wouldn't suggest really and relies on a bug in versions 7 and older. ie:

    Set EngineBehavior 70
    *** Last physically entered from each group
    Select * From Customers ;
        group By package ;
        into Cursor result ;
        nofilter
    Browse
    
    *** Or ordered by something - this one corresponds to unique index trick
    Select * from ;
     (Select * From Customers order by 1 desc) t ;
        group By Package ;
        into Cursor result ;
        nofilter
    browse
    Set EngineBehavior 90