Lone Warriour
Lone Warriour

Reputation: 15

How to update a column based on count of another column from another table using any condition in visual foxpro?

SET STEP ON
Close Databases
Cd e:\ksv\Data
Use ohd IN 0 shared
Use cus IN 0 shared

SELECT * FROM cus inTO TABLE tempcus
ALTER table tempcus ADD COLUMN totalsold int
UPDATE tempcus SET totalsold=RECCOUNT(ohd.status='5') WHERE tempcus.customer=ohd.customer
SELECT * FROM tempcus INTO CURSOR cur
BROWSE

I have tried the above code and i am getting an error saying invalid table number , can someone help me with this.

Upvotes: 0

Views: 813

Answers (2)

DRapp
DRapp

Reputation: 48179

In VFP, there is a REPLACE command which allows you to replace one or more fields based on whatever values, even if variable results from other queries... or fixed values. Ex: This works on whatever table is the current selected work area and whatever row it is on, unless you apply a scope clause (for condition).

Sample only for context of REPLACE command

use SomeOtherTable in 0 shared
select SomeOtherTable
replace SomeNumberField with 1.234, SomeStringField with 'Hello', etc...

or with condition (bogus, just to show you can apply to multiple rows.

replace SomeNumberField with SomeNumberField * 3 for StatusField = 'X'

Now, back to your original content. It appears you are trying to get a result temporary table with a total number of records from the OHD table where the status = 5. VFP allows you to run SQL-Select into temporary read-write "cursor" tables, that when closed will delete themselves, yet allows them to be modified (such as browse, or other direct manipulation such as with REPLACE command).

You can get the counts you are looking for with a left-join to a query result set. To help you see the pieces individually, I will do in steps so you can follow, then join into one final.

First, you want a count of all records in the OHD table with status = 5 per customer... the "o" and "c" are ALIAS references in the SQL queries below

SET STEP ON
Close Databases
Cd e:\ksv\Data
Use ohd IN 0 shared
Use cus IN 0 shared

select ;
      o.customer, ;
      count(*) NumberOfRecords ;
   from ;
      OHD o ;
   where ;
      o.status = '5' ;
   group by ;
      o.customer ;
   into ;
      cursor C_JustCountsPerCustomer READWRITE

The "into cursor" part above will create a workable table and give it the name of "C_JustCountsPerCustomer". I have always tried to use "C_" as a prefix to the table name for the sole purpose to know it is a temporary "CURSOR" result and not a real final table, but that is just my historical naming convention applied.

Now, if you did a browse of this result, you would see each customer's ID and how many with status = '5'. The resulting table "cursor" is like any other table opened and you could index as you need and browse, etc. But this only will give records that HAD status of '5'. But you could have more customers that never had a '5' status record.

Now, getting all your customers and their respective counts into one result table "cursor". I can take the above query and use within a SQL-Select via a LEFT-JOIN meaning, give me everything from the first table (left-side), regardless of a matching record found in the second table (right-side). But if there is a match to the right side, give me those values too.

select ;
      c.*, ;
      NVL( C_tmpResult.NumberOfRecords, 0000 ) as NumberOfRecords ;
   from;
      CUS c ;
         LEFT JOIN ;
         (select ;
                o.customer, ;
                count(*) NumberOfRecords ;
             from ;
                OHD o ;
             where ;
                o.status = '5' ;
             group by ;
                o.customer ) C_tmpResult ;
            ON ;
               c.customer = C_tmpResult.customer ;
   into ;
      cursor C_CusWithCounts readwrite 

So, you can see the left-join uses the first query to get the counts, but the primary part of the query gets records from the customer table (alias "c") and is joined on the common customer id column. The "NVL()" states if there IS a value in the C_tmpResult table for the given customer, grab that. If not, assume a count of 0. Yes, I explicitly have 0000 to force a minimum final width to 4 digits in the result in case the first customer does not have any and it make the column only 1 digit wide.

Anyhow, at the end, you would have your result temporary table (cursor) with the customer information AND the count I think you are looking for. You should be able to do a browse and good to go.

Upvotes: 0

Ed Pecyna
Ed Pecyna

Reputation: 411

RECCOUNT() function only gives you a record count for a workarea# or alias, e.g. RECCOUNT("ohd") will give total record count of ohd table.

You want something like:

SELECT COUNT(*) totalsold,cus.customer FROM cus JOIN ohd ON cus.customer=ohd.customer WHERE ohd.cstatus='5' INTO CURSOR cur GROUP BY cus.customer
BROWSE

Upvotes: 1

Related Questions