Cezary H. Noweta wrote:

CREATE TABLE points AS WITH cte(x,y,n) AS (SELECT (random() % 10 + 10) % 10 + 1, (random() % 10 + 10) % 10 + 1, 1 UNION ALL SELECT (random() % 10 + 10) % 10 + 1, (random() % 10 + 10) % 10 + 1, n + 1 FROM cte WHERE n < 100) SELECT x, y FROM cte;

and

CREATE TABLE xaxis AS SELECT x, COUNT(x) AS n FROM points GROUP BY x;
CREATE TABLE yaxis AS SELECT y, COUNT(y) AS n FROM points GROUP BY y;

For example for two points (1,2); (1,-4)

xaxis(x, n):
1 2

yaxis(y, n):
-4 1
2 1

xaxis <== points(x, y) ==> yaxis:
         1 -4
         1  2

``points(x, y)'' could have (CASCADING) FOREIGN KEY x=>xaxis.x and y=>yaxis.y and DELETE TRIGGERs which could adjust counters in ``*axis'' tables (DELETEing FROM xaxis WHERE x==OLD.x AND n==0 and FROM yaxis WHERE y==OLD.y AND n==0; alternatively ``*axis'' could have UPDATE TRIGGERs which could DELETE FROM points when ``n'' column had achieved 0 or less then nX/nY -- triggers must be supressed while creating a ``*axis'' table in the latter case).

Then ``iteratively'' (not ``recusively'') DELETE from ``*axis'' WHERE n < threshold until there are no too small Xs/Ys or tables are empty.

(1)
DELETE FROM xaxis WHERE n < nX;
DELETE FROM yaxis WHERE n < nY;

(2)
which fire CASCADE DELETE of relations FROM points

(3)
which fires DELETE TRIGGERs of points

(4)
which adjust referenced xaxis.n and y.axis.n

(4a)
and further DELETE FROM *axis WHERE n == 0

(4b)
and further DELETE FROM *axis WHERE n < nX/nY

(4c)
and further fire UPDATE TRIGGERs of *axis, which in turn further do (4a) or (4b).

Cezary, how about this solution with a trigger only on xaxis and on yaxis?
AFTER DELETE FROM xaxis:
- update yaxis set n=n-1 where y in (select y from points where x=old.x)
- delete points where x=old.x
- delete yaxis where n<ny
AFTER DELETE FROM yaxis:
(same with x and y reversed)

Now, with pragma recursive_triggers this might do the whole job if the initial deletes(1) are executed. There is a limit on the recursion (/ iteration) depth. And this solution requires at most nx+ny iterations, where nx is the number of xaxis rows and ny the number of yaxis rows,

On the other hand, if this is not a constest in purely sql programming, why not have a programme loop with a single delete, and no derived *axis tables. For instance using tclsh:


while 1 {
    db eval {
DELETE FROM points
WHERE x IN (
SELECT x FROM points GROUP BY x HAVING COUNT(*)<(SELECT nx FROM params)
        )
OR y IN (
SELECT y FROM points GROUP BY y HAVING COUNT(*)<(SELECT ny FROM params)
        )
;
    }
    if {![db changes]} break
} ;# end loop


E.Pasma
_______________________________________________
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to