Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
Is there a pure SQL way without Scan ?
Message
From
09/08/2006 05:09:56
 
 
To
08/08/2006 20:38:37
General information
Forum:
Visual FoxPro
Category:
Databases,Tables, Views, Indexing and SQL syntax
Miscellaneous
Thread ID:
01143938
Message ID:
01144024
Views:
17
Well,

look on this:
CLOSE DATABASES all
CLOSE TABLES all

*-- create simple test data
CREATE CURSOR t_erg		(cPeriod c(1), cSalesman c(1), nSales n(9,2), nPeriodPerc n(17,2) )
CREATE CURSOR t_data	(cPeriod c(1), cSalesman c(1), nSales n(9,2))

FOR lnRun = 1 TO 2
	INSERT INTO t_data VALUES ("1", "A", 0500)
	INSERT INTO t_data VALUES ("1", "B", 0700)
	INSERT INTO t_data VALUES ("1", "C", 0900)
	INSERT INTO t_data VALUES ("1", "D", 0300)
	INSERT INTO t_data VALUES ("1", "E", 0400)
	INSERT INTO t_data VALUES ("2", "A", 0100)
	INSERT INTO t_data VALUES ("2", "B", 0700)
	INSERT INTO t_data VALUES ("2", "C", 0900)
	INSERT INTO t_data VALUES ("2", "D", 1300)
	INSERT INTO t_data VALUES ("2", "E", 1400)
	INSERT INTO t_data VALUES ("3", "A", 0100)
	INSERT INTO t_data VALUES ("3", "B", 1700)
	INSERT INTO t_data VALUES ("3", "C", 0900)
	INSERT INTO t_data VALUES ("3", "D", 0800)
	INSERT INTO t_data VALUES ("3", "E", 0200)
	INSERT INTO t_data VALUES ("4", "A", 1100)
	INSERT INTO t_data VALUES ("4", "B", 1107)
	INSERT INTO t_data VALUES ("4", "C", 1110)
	INSERT INTO t_data VALUES ("4", "D", 0300)
	INSERT INTO t_data VALUES ("4", "E", 0400)
NEXT


* BUILD DATA DOMAIN, where cPeriod, cSalesman  is a pk !

SELECT cPeriod, cSalesman ;
		, SUM(nSales) as nSales ;
	FROM t_data ;
	GROUP BY 1,2 INTO CURSOR t_sum

* but, vfp DON'T SUPPORT THE SQL direct SOLUTION
	
SELECT t_sum2.*;
, 100*t_sum2.nSales/t_periods.sum_Period as nPeriodPerc ; 
FROM ;
	(SELECT * FROM t_sum ;
	  WHERE nSales IN (SELECT TOP 2 nSales FROM t_sum X WHERE cPeriod=t_sum.cPeriod ORDER BY 1 desc)) t_sum2 ;
inner join;
	(SELECT ;
			cPeriod ;
			; && example: in reality lots of calculated fields 
			, SUM(nSales) as sum_Period ; 
		FROM t_sum ;
		GROUP BY 1 ) t_periods;
	on t_sum2.cPeriod = t_periods.cPeriod;
		HAVING nPeriodPerc >= 24.5;
		order by 1,nSales desc

CLEAR

* indirect way ( implement a group counting with VFP with the HAVING scan behaviour ):

* Step 1
* BUILD DATA DOMAIN ORDERED !, where cPeriod, cSalesman  is a pk !

SELECT cPeriod, cSalesman ;
		, SUM(nSales) as nSales ;
		FROM t_data ;
		GROUP BY 1,2 ORDER BY 1,3 DESC ;
	INTO CURSOR t_sum
		
GROUP_ROW_INIT()
		
SELECT t_sum2.*;
, 100*t_sum2.nSales/t_periods.sum_Period as nPeriodPerc ; 
FROM ;
	(SELECT *	;
		FROM t_sum	HAVING GROUP_ROW(cPeriod) <=2 ) t_sum2 ;
inner join;
	(SELECT cPeriod ;
			, SUM(nSales) as sum_Period ; 
		FROM t_sum ;
		GROUP BY 1 ) t_periods;
	on t_sum2.cPeriod = t_periods.cPeriod;
		HAVING nPeriodPerc >= 24.5;
		ORDER BY 1,nSales desc;
	INTO CURSOR t_erg

GROUP_ROW_DESTROY()

USE IN t_sum

BROWSE

* this is an "ONE SELECT SOLUTION"

GROUP_ROW_INIT()

SELECT t_sum2.*;
, 100*t_sum2.nSales/t_periods.sum_Period as nPeriodPerc ; 
FROM FORCE ;
	(SELECT *	;
		FROM (SELECT cPeriod, cSalesman ;
				, SUM(nSales) as nSales ;
				FROM t_data ;
				GROUP BY 1,2;
				ORDER BY 1,3 DESC) t_sum;
	HAVING GROUP_ROW(cPeriod) <= 2 ) t_sum2 ;
INNER JOIN;
	(SELECT cPeriod ;
			, SUM(nSales) as sum_Period ; 
		FROM t_data ;
		GROUP BY 1 ) t_periods;
	ON t_periods.cPeriod = t_sum2.cPeriod ;
		HAVING nPeriodPerc >= 24.5;
	order by 1,nSales desc;
	INTO CURSOR t_erg1
	
GROUP_ROW_DESTROY()
BROWSE


*********************************************** GROUP COUNT FUNCTION **********

proc GROUP_ROW_INIT
	PUBLIC groupCount,groupKey
	groupCount	 = NULL
ENDPROC

proc GROUP_ROW_DESTROY
	RELEASE groupCount,groupKey
ENDPROC

PROC GROUP_ROW(_groupkey)

IF ISNULL(m.groupCount)
	groupKey	= NULL	&& this version doesn't support NULL key, it is simple to extend ...
	groupCount	= 0
	RETURN 0
ENDIF

IF M.groupkey == M._groupkey
	groupCount	= m.groupCount + 1
	RETURN m.groupCount
ENDIF

groupkey = M._groupkey
groupCount	 = 1
RETURN 1
Previous
Reply
Map
View

Click here to load this message in the networking platform