2017-11-16 4 views
1

2つの列がidvalのテーブルがあるとします。私は全く同じと反対のものが存在するところにある別のすべてのidを見つけることを望んでいませんでしたval。たとえば、次の表等しい値と反対の値のSQL照会

id | val 
------+------ 
    1 | 3 
    2 | 5 
    2 | -5 
    1 | 4 
    2 | 6 
    3 | 9 
    2 | -6 
    3 | -9 

があると私は結果が値5, -56, -6があるので、結果セットに

result 
    2 
    3 

2になりたいです。 9, -9のため、3が結果セットに含まれています。

where existsを使用してこれを行うことができます。

select distinct tab1.id from tab tab1 
where exists (
    select * from tab tab2 
    where tab1.id = tab2.id 
    and tab1.val = -tab2.val 
); 

ような何かはしかし、私はそれは、ネストされたループのように計算されるので、このようなクエリは、時間複雑O(n^2)を持っていることを心配します(?)。しかし、これを計算するには、O(n)時間でテーブルをスキャンして(そして、以前に見た結果を、O(1)ルックアップ時間のデータ構造に記録する)ことができます。そのようなクエリを書く最適な方法は何ですか?

+0

パフォーマンスを前提とする前に、クエリプランをチェック(および投稿)します。 –

+1

ここにネストされたループはありません。おそらく少しのデカルト製品の状況の種類、しかし何もひどい。それは、INNER JOIN(これもこの状況で動作する)と同様に機能しなければならない良い相関サブクエリのように見えます。 – JNevill

答えて

0

リクエストの説明とインデックスの設定方法を説明してください。

が、それはあまりにも、このように行うことができることがある:

WITH pos AS (
    SELECT id, val FROM tab WHERE val > 0), 
neg AS (
    SELECT id, val FROM tab WHERE val < 0) 
SELECT DISTINCT id 
    FROM pos JOIN neg USING (id) 
WHERE pos.val = neg.val; 

右物価スライドでは、これが迅速である可能性があります。データの量にも依存します。

関連する問題