সুতরাং, উদাহরণস্বরূপ। দুটি প্রান্তের সংযুক্ত গ্রুপ সহ একটি সাধারণ টেবিল:
drop table lines;
create table lines ( id integer primary key, geom geometry(linestring) );
insert into lines (id, geom) values ( 1, 'LINESTRING(0 0, 0 1)');
insert into lines (id, geom) values ( 2, 'LINESTRING(0 1, 1 1)');
insert into lines (id, geom) values ( 3, 'LINESTRING(1 1, 1 2)');
insert into lines (id, geom) values ( 4, 'LINESTRING(1 2, 2 2)');
insert into lines (id, geom) values ( 11, 'LINESTRING(10 10, 10 11)');
insert into lines (id, geom) values ( 12, 'LINESTRING(10 11, 11 11)');
insert into lines (id, geom) values ( 13, 'LINESTRING(11 11, 11 12)');
insert into lines (id, geom) values ( 14, 'LINESTRING(11 12, 12 12)');
create index lines_gix on lines using gist(geom);
এখন, এখানে একটি পুনরাবৃত্ত ফাংশন যা একটি প্রান্তের আইডি দেওয়া, সমস্ত প্রান্ত স্পর্শ করে যা স্পর্শ করে:
CREATE OR REPLACE FUNCTION find_connected(integer) returns integer[] AS
$$
WITH RECURSIVE lines_r AS (
SELECT ARRAY[id] AS idlist, geom, id
FROM lines
WHERE id = $1
UNION ALL
SELECT array_append(lines_r.idlist, lines.id) AS idlist,
lines.geom AS geom,
lines.id AS id
FROM lines, lines_r
WHERE ST_Touches(lines.geom, lines_r.geom)
AND NOT lines_r.idlist @> ARRAY[lines.id]
)
SELECT
array_agg(id) AS idlist
FROM lines_r
$$
LANGUAGE 'sql';
এটি কেবল আমাদের প্রতিটি গোষ্ঠী জমে যাওয়ার পরে খুঁজে বের করার প্রয়োজন রাখে, এমন একটি প্রান্তের আইডি যা ইতিমধ্যে কোনও গোষ্ঠীর অংশ নয়। দুঃখজনকভাবে, যার জন্য দ্বিতীয় পুনরাবৃত্তি কোয়েরি প্রয়োজন requires
WITH RECURSIVE groups_r AS (
(SELECT find_connected(id) AS idlist,
find_connected(id) AS grouplist,
id FROM lines WHERE id = 1)
UNION ALL
(SELECT array_cat(groups_r.idlist,find_connected(lines.id)) AS idlist,
find_connected(lines.id) AS grouplist,
lines.id
FROM lines, groups_r
WHERE NOT idlist @> ARRAY[lines.id]
LIMIT 1)
)
SELECT id, grouplist
FROM groups_r;
যা একসাথে নেওয়া বীজ আইডি এবং প্রতিটি গ্রুপ এটি জমে একটি দুর্দান্ত সেট ফেরত দেয়। আমি ম্যাপিংয়ের জন্য জ্যামিতি তৈরির জন্য আইডি এর অ্যারেগুলিকে আবারো কোয়েরিতে রূপান্তরিত করার জন্য এটি একটি অনুশীলন হিসাবে পাঠকের কাছে রেখেছি।
id | grouplist
----+---------------
1 | {1,2,3,4}
11 | {11,12,13,14}
(2 rows)