SELECT cdr && cdr is call records in previous SET ORDER TO _Primary &&your Primary key replace _primary with your name *or INDEX ON CDR.DNIS+CDR.StartDT TAG _Primary SET EXACT OFF SET STEP ON SELECT; cdr.DNIS+cdr.StartDT AS CDR_Uni,; && unifier of cdr Rate.DEST AS CDR_Dest,; Rate.CODE AS CDR_Code,; Rate.Rate AS CDR_Rate,; cdr.Duration AS CDR_Duration,; IIF(cdr.Duration >0,; IIF(cdr.Duration<Rate.MinimumSec,; (Rate.MinimumSec/60), (CEILING(cdr.Duration/Rate.INCREMENT)/60*Rate.INCREMENT)),; 0) AS CDR_billdur,; IIF(cdr.Duration > 0,Rate.Rate*cdr.billdur,0) AS CDR_Charge; &&MayBe You need do that down in the replace because of first normalising BillDur FROM Rate,; INNER JOIN cdr; ON ALLTRIM(cdr.dnis)=Rate.CODE; AND !EMPTY(cdr.DEST); INTO CURSOR curHelp *this gives Code "0115411" as well as "01154" for dnis="0115411555555" *now lets see how to get rid of the double records SELECT; curHelp.CDR_Uni,; curHelp.CDR_Code,; MAX(LEN(ALLTRIM(curHelp.CDR_Code); FROM curHelp; INTO CURSOR curSum; GROUP BY 1,2 *only the longest codes for a CDR_Uni should survive SELECT; curHelp.CDR_Uni,; curHelp.CDR_Dest,; curHelp.CDR_Code,; curHelp.CDR_Rate,; curHelp.CDR_Duration,; curHelp.CDR_billdur,; curHelp.CDR_Charge; FROM curHelp,; INNER JOIN curSum; ON curSum.CDR_Uni==curHelp.CDR_Uni; AND curSum.CDR_Code==curHelp.CDR_Code; INTO CURSOR curHelp1 *now we should have the rates for the longest possible code *************** /new part ************************** SET RELATION TO CDR_Uni INTO CDR *This is a 1 To 1 relation so no need to SET SKIP REPLACE; CDR.Rate WITH CDR_Rate,; CDR.DEST WITH CDR_Dest,; CDR.CODE WITH CDR_Code,; CDR.BillDur WITH CDR_BillDur,; CDR.Charge WITH CDR_Charge; ALL SET RELATION TO USE USE IN curSum USE IN curHelp SELECT cdr SET ORDER TOHTH