Du kan bruge intervaldatatyperne og gemme hver usammenhængende type i en række.
Til din prøve:
-- The table
CREATE TABLE sets(id text, range int4range);
-- Values of set A
INSERT INTO sets VALUES('A', '[1,1]'),('A','[7,7]'),('A','[9,13]');
-- Values of set B
INSERT INTO sets VALUES('B','[1,1]'),('B','[7,7]'),('B','[10,10]');
For at kontrollere, om B er en delmængde af A, kan du forbinde begge med alle tupler, hvor A's område indeholder B's område:
SELECT b.range
FROM sets b JOIN sets a
ON a.range @> b.range
WHERE a.id='A' AND b.id='B'
Med det kan du kontrollere, om alle værdierne fra sæt B er i ovenstående resultat (hvilket vil betyde, at alle områderne af B er indeholdt af mindst ét område af A):
SELECT NOT EXISTS(
SELECT 1 FROM sets q WHERE q.id='B' AND q.range NOT IN (
SELECT b.range
FROM sets b JOIN sets a
ON a.range @> b.range
WHERE a.id='A' AND b.id='B'
));
For at få krydset, kan du krydsforbinde begge og ekskludere de tomme:
SELECT * FROM (
SELECT a.range * b.range AS intersec
FROM sets a CROSS JOIN sets b WHERE a.id='A' AND b.id='B'
) i WHERE NOT isempty(i.intersec);
Et problem ved denne tilgang er, at du kun skal holde usammenhængende rangeS gennem forskellige tupler. For eksempel skal området [1,5] og [4,7] fra et sæt ligge i en tupel med kun [1,7]. For at være sikker på det, kan du indsætte dem i en midlertidig tabel (mens du indsætter eller opdaterer), de krydser selve bordet med tupler, der overlapper, og de slutter sig til dem og holder de andre, som de er.