Thank you Cezary and others who commented.

For some reason, I did not receive email from Cezary, only comments on it.

I was under impression that RECURSIVE can not be used in sub-query. I see that 
it can.

But, most importantly, could you elaborate more on how it works. I agree it is 
n-to-n problem. But the solution merges all data into a single cell with all 
pairs, which is counter to relational solution.

I ask for details, if possible, because the actual problem  that I have to 
solve is a bit more complicated: I have two of such lists good(x,y) and 
bad(x,y) with a coupling condition that if x is removed from one list, it must 
be removed from the other. This is easy to add for ones who understand how it 
works. 

Roman

________________________________________
From: sqlite-users [sqlite-users-boun...@mailinglists.sqlite.org] on behalf of 
E.Pasma [pasm...@concepts.nl]
Sent: Friday, May 04, 2018 10:35 AM
To: SQLite mailing list
Subject: Re: [sqlite] probably recursive?

Cezary H. Noweta wrote:
>>
>>> At the beginning I would like to agree with that the problem is
>>> iterative rather then recursive one. However....
R. Smith wrote:
>
>> LOL, that might be the hackiest query I ever seen, but kudos mate,
>> that's bloody marvellous!

Cezary, thanks for the diverting solution. I've been looking into
solving sudokus along the same lines. A function GROUP_SPLIT as an
inverse of GROUP_CONCAT would be handy here. Below is the query as it
looks when there was such a function, or actually a (function like)
virtual table with column elem. It is exactly half the size.
Nevertheless the fun is to achieve the goal purely in SQL.
Thanks, E Pasma.

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;

WITH
   params(nx, ny) AS (SELECT 6, 8),
   main(elem, rest) AS (
     SELECT NULL, (
       WITH
         state(clock, points, xaxis, yaxis, nxmin, nxmax, nymin,
nymax) AS (
           SELECT
             0,
             (SELECT GROUP_CONCAT(x || ' ' || y) FROM points),
(SELECT GROUP_CONCAT(x || ' ' || n) FROM (SELECT x, COUNT(x) n FROM
points GROUP BY x)), (SELECT GROUP_CONCAT(y || ' ' || n) FROM (SELECT
y, COUNT(y) n FROM points GROUP BY y)), (SELECT MIN(n) FROM (SELECT x,
COUNT(x) n FROM points GROUP BY x)), (SELECT MAX(n) FROM (SELECT x,
COUNT(x) n FROM points GROUP BY x)), (SELECT MIN(n) FROM (SELECT y,
COUNT(y) n FROM points GROUP BY y)), (SELECT MAX(n) FROM (SELECT y,
COUNT(y) n FROM points GROUP BY y))
           UNION ALL
           SELECT
             (clock + 1) % 3,
             CASE clock WHEN 0 THEN
             (SELECT GROUP_CONCAT(x || ' ' || y) FROM (
               SELECT
                 CAST(elem AS INTEGER) x,
                 CAST(SUBSTR(elem, INSTR(elem, ' ')) AS INTEGER) y
               FROM GROUP_SPLIT (state.points)
             )
             WHERE (x NOT IN (
               SELECT x FROM (
                 SELECT
                   CAST(elem AS INTEGER) x,
                   CAST(SUBSTR(elem, INSTR(elem, ' ')) AS INTEGER) n
                   FROM GROUP_SPLIT (state.xaxis)
               ) WHERE n < (SELECT nx FROM params)
             )) AND (y NOT IN (
               SELECT y FROM (
                 SELECT
                   CAST(elem AS INTEGER) y,
                   CAST(SUBSTR(elem, INSTR(elem, ' ')) AS INTEGER) n
                   FROM GROUP_SPLIT (state.yaxis)
               ) WHERE n < (SELECT ny FROM params)
             ))) ELSE points END,
             CASE clock WHEN 1 THEN
(SELECT GROUP_CONCAT(x || ' ' || n) FROM (SELECT x, COUNT(x) n FROM (
               SELECT
                 CAST(elem AS INTEGER) x
               FROM GROUP_SPLIT (state.points)
             ) GROUP BY x)) ELSE xaxis END,
             CASE clock WHEN 1 THEN
(SELECT GROUP_CONCAT(y || ' ' || n) FROM (SELECT y, COUNT(y) n FROM (
               SELECT
                 CAST(SUBSTR(elem, INSTR(elem, ' ')) AS INTEGER) y
               FROM GROUP_SPLIT (state.points)
             ) GROUP BY y)) ELSE yaxis END,
             CASE clock WHEN 2 THEN
             (SELECT MIN(n) FROM (
               SELECT
                 CAST(SUBSTR(elem, INSTR(elem, ' ')) AS INTEGER) n
               FROM GROUP_SPLIT (state.xaxis)
             )) ELSE nxmin END,
             CASE clock WHEN 2 THEN
             (SELECT MAX(n) FROM (
               SELECT
                 CAST(SUBSTR(elem, INSTR(elem, ' ')) AS INTEGER) n
               FROM GROUP_SPLIT (state.xaxis)
             )) ELSE nxmax END,
             CASE clock WHEN 2 THEN
             (SELECT MIN(n) FROM (
               SELECT
                 CAST(SUBSTR(elem, INSTR(elem, ' ')) AS INTEGER) n
               FROM GROUP_SPLIT (state.yaxis)
             )) ELSE nymin END,
             CASE clock WHEN 2 THEN
             (SELECT MAX(n) FROM (
               SELECT
                 CAST(SUBSTR(elem, INSTR(elem, ' ')) AS INTEGER) n
               FROM GROUP_SPLIT (state.yaxis)
             )) ELSE nymax END
           FROM state
           WHERE (SELECT nx FROM params) BETWEEN nxmin + 1 AND nxmax OR
                 (SELECT ny FROM params) BETWEEN nymin + 1 AND nymax
) SELECT points FROM state WHERE nxmin >= (SELECT nx FROM params) AND
nymin >= (SELECT ny FROM params)
     )
     UNION ALL
     SELECT
SUBSTR(rest, 1, IFNULL(NULLIF(INSTR(rest, ','), 0) - 1, LENGTH(rest))),
       SUBSTR(rest, NULLIF(INSTR(rest, ','), 0) + 1)
     FROM main
     WHERE rest IS NOT NULL
   )
SELECT
   CAST(elem AS INTEGER) x,
   CAST(SUBSTR(elem, INSTR(elem, ' ')) AS INTEGER) y
   FROM main WHERE elem IS NOT NULL
;


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

Reply via email to