27

Postgresqlでそのようなクエリを実行する方法を知っている人はいますか?

SELECT * 
FROM tabA 
WHERE NOT EXISTS (
    SELECT * 
    FROM tabB 
    WHERE tabB.id = tabA.id
)

このようなクエリを実行すると、postgresql は " ERROR: Greenplum Database does not yet support that query."と文句を言います。

編集:そして、これはどうですか:

SELECT * 
FROM tabA 
WHERE NOT EXISTS (
    SELECT * 
    FROM tabB WHERE tabB.id = tabA.id AND tabB.id2 = tabA.id2
)

編集:
@ypercube から提供された 4 つの回答について、postgresql 8.2.15 でテストしました。結論は次のとおりです

。1)上記の質問で述べたように、このバージョンのpostgresqlでは最初のものは機能しません。エラーメッセージもそこにあります。

2) 他の 3 つの回答の実行速度は、(3)LEFT JOIN > (4)EXCEPT >> (2)NOT IN です。
具体的には、同じ構文のクエリの場合、(3)LEFT JOIN は約 5580 ミリ秒、(4)EXCEPT は約 13502 ミリ秒、(2)NOT IN は 100000 ミリ秒以上かかります (実際、私は util が終了するのを待ちませんでした)。
NOT IN 句が非常に遅い特定の理由はありますか?
チェン

4

3 に答える 3

32

この種のクエリを実行するには、3 つの (主な) 方法があります。

  1. NOT EXISTS相関サブクエリ

  2. NOT INサブクエリ

  3. LEFT JOINIS NULLチェックあり:

最初の方法が Greenplum で機能することがわかりました。@Marco と @juergen が 2 番目の方法を提供してくれました。これは 3 番目のもので、Greenplum の制限を回避する可能性があります。

SELECT tabA.* 
FROM 
    tabA 
  LEFT JOIN 
    tabB 
      ON  tabB.id = tabA.id 
      AND tabB.id2 = tabA.id2
WHERE tabB.id IS NULL ;

これ(4番目の方法)はPostgres(EXCEPT演算子をサポート)でも機能します:

SELECT a.*
FROM a
WHERE id IN
      ( SELECT id
        FROM a
      EXCEPT
        SELECT id
        FROM b
      ) ; 

SQL-Fiddleでテスト済み(4 つすべてが Postgres で動作すること)。

于 2012-06-28T05:58:56.707 に答える
5

省略したエラーの部分は、正しい方向を示していた可能性があります。「DETAIL: クエリには相関サブクエリが含まれています」と表示されたと思います。したがって、これらを結合または非相関サブクエリで書き直す必要があります。

SELECT * FROM tabA WHERE id NOT IN (SELECT id FROM tabB);

2番目のクエリについては、試してください

SELECT * FROM tabA WHERE (id, id2) NOT IN (SELECT id, id2 FROM tabB);
于 2012-06-28T05:44:03.780 に答える
2
SELECT * FROM tabA 
WHERE id not in  (SELECT id FROM tabB)
于 2012-06-28T05:43:38.210 に答える