2016-01-18 10 views
6

では、私はEXIST句を使用するクエリを実行しようとしています:スパーク交換が存在し、

select <...>  
    from A, B, C 
where 
    A.FK_1 = B.PK and 
    A.FK_2 = C.PK and 
    exists (select A.ID from <subquery 1>) or 
    exists (select A.ID from <subquery 2>) 

残念ながら、これはサポートされていないようです。

select <...>  
    from A, B, C 
where 
    A.FK_1 = B.PK and 
    A.FK_2 = C.PK and 
    A.ID in (select ID from ...) or 
    A.ID in (select ID from ...) 

残念ながら、またIN句はサポートされていないように思わ:私はまたIN句でEXISTS句を交換しようとしています。

希望の結果を得るSQLクエリをどのように書くことができますか?私はUNIONなどの別のJOINと第二OR句として、原則的にWHERE句をモデル化することができますが、それは超不器用なようだ。..

EDIT:可能な解決策の数を一覧表示します。

ソリューション1

select <...>  
    from A, B, C 
     (select ID from ...) as exist_clause_1, 
     (select ID from ...) as exist_clause_2, 
where 
    A.FK_1 = B.PK and 
    A.FK_2 = C.PK and 
    A.ID = exist_clause_1.ID or 
    A.ID = exist_clause_2.ID 

ソリューション2

select <...>  
    from A, B, C 
     ((select ID from ...) UNION 
     (select ID from ...) 
     ) as exist_clause, 
where 
    A.FK_1 = B.PK and 
    A.FK_2 = C.PK and 
    A.ID = exist_clause.ID 
+0

最初のクエリテンプレートには、存在するフォームのEXISTS呼び出しはありませんか?(E.ID = A.IDの場合は EからE.IDを選択してください)) '? – philipxy

答えて

13

SparkSQLは現在& InをEXISTSはありません。 "(Latest) Spark SQL/DataFrames and Datasets Guide/Supported Hive Features"

EXISTS & INは、常にJOINまたはLEFT SEMI JOINを使用して書き換えられます。 "Although Apache Spark SQL currently does not support IN or EXISTS subqueries, you can efficiently implement the semantics by rewriting queries to use LEFT SEMI JOIN." ORは常にUNIONを使用して書き換えることができます。 AND NOTはEXCEPTを使用して書き換えることができます。

  • DBAは、各ベーステーブルのための述語を与える列を持つTT.C,...

    の表は、真のいくつか述語(カラム名によってパラメータ声明を)作るの行を保持しているTをTC、...)

  • JOINは、そのアルファts '述語は真です。 UNIONの場合、OR; EXCEPTの場合はAND NOTです。
  • SELECT DISTINCTkept columnsFROMT [Tの述語]列を落としEXISTS行を保持します。
  • TLEFT SEMI JOINU [Tの述語AND U述語] U-列のみをEXISTS行を保持します。
  • TWHEREcondition T述語AND 条件行を保持します。あなたが作曲および/またはクエリを再編成する簡単なロジック書き換えルールを使用することができますSQLに対応する心述語表現に保つことによってそのよう

(照会再一般this answerを参照してください。)

。たとえば、UNIONを使用すると、読みやすさや実行の面で「不器用」になる必要はありません。

元の質問からは、UNIONを使用できると理解していて、EXISTSとINを元のクエリから除外して、あなたの疑問を修正しました。 ORを切除する別の変種もここにあります。

select <...>  
    from A, B, C, (select ID from ...) as e 
    where 
     A.FK_1 = B.PK and 
     A.FK_2 = C.PK and 
     A.ID = e.id 
union 
    select <...>  
    from A, B, C, (select ID from ...) as e 
    where 
     A.FK_1 = B.PK and 
     A.FK_2 = C.PK and 
     A.ID = e.ID 

解決策1は、あなたがそう考えるものをしません。 exists_clauseテーブルのうちの1つだけが空の場合(つまり、IDが他のテーブルで使用可能であっても)、テーブルのFROM外積は空であり、行は返されません。 ("An Unintuitive Consequence of SQL Semantics": Chapter 6 The Database Language SQL sidebar page 264 of Database Systems: The Complete Book 2nd Edition.) FROMはテーブルの行の名前を導入するだけではなく、CROSS JOININGおよび/またはOUTER JOININGした後にON(INNER JOINsの場合)およびWHEREフィルタリングをいくつか行います。

パフォーマンスは、通常、同じ行を返す異なる式によって異なります。これはDBMSの最適化に依存します。 DBMSやプログラマが知ることができるかもしれない多くの詳細、もしそれが分かっているかどうか、最良のバランスであるかどうかは問合せを評価する最善の方法とそれを書く最良の方法に影響します。しかし、WHERE内の行ごとに2つのORed副選択を実行すると(元の照会の場合と同様)、2つのSELECTの1つのUNIONを実行するよりも必ずしも優れているわけではありません。

+0

返信いただきありがとうございます!私は、各select文に対してサブクエリを使用し、すべての基本関係とサブクエリによって計算された関係との間で1つの巨大な結合を実行しました。私は完全に理解していませんが、あなたの解決策は多少異なると思います。より正確にクエリテンプレートをスケッチできますか? (私の現在のソリューションを追加する質問を編集しています) – Radu

+0

また、パフォーマンスは通常異なることに言及します。それがなぜそのようになるのか、ヒントを教えてください。 – Radu

+0

私はあなたのコメントに答えるために私の答えを更新しました。パフォーマンスが向上したら、リレーショナル・クエリの最適化についてお読みください。これは実際にリレーショナル・クエリの実装を意味します。オンラインの一般的な書籍や商品別の書籍、GoogleのSQLのパフォーマンスなどが多数あります。 – philipxy

関連する問題