Spark替换EXISTS和IN

时间:2016-01-18 18:23:23

标签: sql apache-spark-sql

我正在尝试运行使用EXIST子句的查询:

poll2

不幸的是,这似乎不受支持。我还尝试用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>) 子句替换EXISTS子句:

IN

不幸的是,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 ...) 子句似乎也不受支持。

关于如何编写实现所需结果的SQL查询的任何想法?我原则上可以将IN子句建模为另一个WHERE,将第二个JOIN子句建模为OR,但它看起来非常笨拙......

编辑:列出一些可能的解决方案。

解决方案1 ​​

UNION

解决方案2

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

1 个答案:

答案 0 :(得分:15)

SparkSQL目前没有EXISTS&amp;在。 "(Latest) Spark SQL / DataFrames and Datasets Guide / Supported Hive Features"

EXISTS&amp;始终可以使用JOIN或LEFT SEMI JOIN重写IN。 "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."或者总是可以使用UNION重写。 AND NOT可以使用EXCEPT重写。

一个表包含使某些谓词(由列名参数化的语句)为true的行:

  • DBA为每个基表 T 提供带 T.C,... 列的谓词: T TC ,...)
  • JOIN保存使其参数的AND'谓词为真的行;对于UNION,OR;对于EXCEPT,AND NOT。
  • SELECT DISTINCT kept columns FROM T 包含EXISTS 删除列的行 [谓词T ]。
  • T LEFT SEMI JOIN U 保存EXISTS U-only列的行 [< em> U 的T 和谓词的谓词。
  • T WHERE condition 包含谓词T AND 的行条件

(重新查询一般见this answer。)

因此,通过记住与SQL对应的谓词表达式,您可以使用简单的逻辑重写规则来编写和/或重新组织查询。例如,在可读性或执行方面,使用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表为空,即即使另一个表中存在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 JOIN,然后ON(对于INNER JOIN)和WHERE过滤掉一些。

对于返回相同行的不同表达式,性能通常是不同的。这取决于DBMS优化。 DBMS和/或程序员可能知道的许多细节,如果可能知道或可能不知道,可能或可能不能达到最佳平衡,会影响评估查询的最佳方式以及编写查询的最佳方式。但是在WHERE中每行执行两个ORed子选择(如在原始查询中,但也包括最后的解决方案2)并不一定比运行两个SELECT的UNION更好(如在我的查询中)。