web-dev-qa-db-ja.com

PostgresqlのNOT EXISTS句

誰もがそのようなクエリを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は約5580msかかり、(4)EXCEPTは約13502msかかり、(2)NOT INは100000以上かかります(実際、utilを待機しませんでしたそれは終わった)。
NOT IN句が非常に遅くなる特別な理由はありますか?
チェン

20
cheng

この種類のクエリを実行するには、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で動作します)。

27
ypercubeᵀᴹ

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

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);
5
Marco Mariani
SELECT * FROM tabA 
WHERE id not in  (SELECT id FROM tabB)
2
juergen d