1

Postgresに保存してクエリしたいデータセット(例では整数であると仮定しましょう)があります。
例:
データ セット A: 1,7,9-13
データ セット B: 1, 7, 10
次のようなクエリを実行したい:
1. B は A のサブセットですか? (はい)
2. A と B の交点は何ですか? (B)
データ セットには、数千の整数範囲を含めることができます。
そのようなデータ分析をサポートする拡張機能があるかどうか疑問に思っていました。
例/リンクをいただければ幸いです。

4

2 に答える 2

0

SQL フィドル

配列や範囲は必要ありません。それは単なる純粋な関係です。

インターセプトは非常に明白です。

select v
from t
where set = 'A'
intersect
select v
from t
where set = 'B'
order by v

そして、サブセットはそれほど難しくありません:

select count(*) = 0
from (
    select v
    from t
    where set = 'B'
    except
    select b.v
    from
        (select v from t where set = 'A') a
        inner join
        (select v from t where set = 'B') b on b.v = a.v
) s
于 2013-03-03T22:59:53.893 に答える
0

範囲データ型を使用して、それぞれの互いに素な型を行に格納できます。

サンプルの場合:

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

B が A のサブセットであるかどうかを確認するには、A の範囲に B の範囲が含まれるすべてのタプルで両方を結合できます。

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

これにより、セット B のすべての値が上記の結果に含まれているかどうかを確認できます (これは、B のすべての範囲が A の少なくとも 1 つの範囲に含まれていることを意味します)。

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

交差点を取得するには、両方をクロス結合して空のものを除外できます。

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

このアプローチに関する 1 つの問題は、異なるタプルを介して互いに素な rangeS のみを保持する必要があることです。たとえば、セットの範囲 [1,5] と [4,7] は、[1,7] のみのタプルに存在する必要があります。それを確実にするために、それらを一時テーブルに挿入し(挿入または更新中に)、重複するタプルでテーブル自体をクロス結合し、それらを結合して他のものをそのままに保ちます。

于 2013-03-03T19:36:34.113 に答える