sql – EXISTS和IN的Spark替换

前端之家收集整理的这篇文章主要介绍了sql – EXISTS和IN的Spark替换前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我试图运行使用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>)

不幸的是,这似乎不受支持.我也尝试用IN子句替换EXISTS子句:

select <...>    
  from A,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子句似乎也不受支持.

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

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

解决方案1

select <...>    
  from A,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,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

解决方法

Sparksql目前没有EXISTS&在. “(Latest) Spark SQL / DataFrames and Datasets Guide / Supported Hive Features”

EXISTS&始终可以使用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.” OR总是可以使用UNION重写. AND NOT可以使用EXCEPT重写.

表保存使一些谓词(由列名参数化的语句)为true的行:

> DBA为每个基表T提供带有列T.C,…:T(T.C,…)的谓词
> JOIN保存使其参数的AND’谓词为真的行;对于UNION,OR;除了以外,AND NOT.
> SELECT DISTINCTkept columnsFROMT保存EXISTS删除列的行[T的谓词].
> TLEFT SEMI JOINU持有EXISTS U-only列的行[U的T和谓词的谓词].
> TWHEREcondition保存T AND条件谓词的行.

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

因此,通过记住与sql对应的谓词表达式,您可以使用直接的逻辑重写规则来组合和/或重新组织查询.例如,在这里使用UNION在可读性或执行方面不需要“笨拙”.

您的原始问题表明您了解可以使用UNION,并且您已在您的问题中编辑了变体,从原始查询删除了EXISTS和IN.这是另一个变体也切除OR.

select <...>    
    from A,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,(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更好(如在我的查询中).

原文链接:https://www.f2er.com/mssql/84342.html

猜你在找的MsSQL相关文章