sql >> Databáze >  >> RDS >> PostgreSQL

Ukládání a dotazování na strom intervalů v PostgreSQL

Můžete použít datové typy rozsahu a uložit každý nesouvislý typ do řádku.

Pro váš vzorek:

-- 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]');

Chcete-li zkontrolovat, zda B je podmnožinou A, můžete obě spojit se všemi n-ticemi, které rozsah A obsahuje rozsah B:

 SELECT b.range
 FROM sets b JOIN sets a
     ON a.range @> b.range
 WHERE a.id='A' AND b.id='B'

S tím můžete zkontrolovat, zda jsou všechny hodnoty ze sady B ve výše uvedeném výsledku (což bude znamenat, že všechny rozsahy B jsou obsaženy alespoň jedním rozsahem 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'
     ));

Chcete-li získat průsečík, můžete obě spojit a vyloučit prázdné:

 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);

Jedním z problémů tohoto přístupu je, že musíte udržovat pouze disjunktní rozsahy prostřednictvím různých n-tic. Například rozsah [1,5] a [4,7] z množiny se musí nacházet v n-tici pouze s [1,7]. Abyste se o tom ujistili, můžete je vložit do dočasné tabulky (během vkládání nebo aktualizace), křížově se připojují k tabulce samotné s n-ticemi, které se překrývají a ty se spojují a ostatní si ponechají tak, jak jsou.



  1. python mysqldb odstranit řádek

  2. Chyba SQL při pokusu o vytvoření nového spouštěče

  3. Proč SQL Server ztrácí milisekundu?

  4. Alternativa k použití klíčového slova LIMIT v poddotazu v MYSQL