gpt4 book ai didi

sql - EXISTS 和 IN 的 Spark 替换

转载 作者:行者123 更新时间:2023-12-04 03:14:58 26 4
gpt4 key购买 nike

我正在尝试运行使用 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>)

不幸的是,这似乎不受支持。我也试过更换 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 ...)

不幸的是,还有 IN条款似乎不受支持。

关于如何编写实现所需结果的 SQL 查询的任何想法?我原则上可以模拟 WHERE条款作为另一个 JOIN第二个 OR条款作为 UNION但它似乎 super 笨拙..

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

解决方案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

最佳答案

SparkSQL 目前没有 EXISTS & IN。 "(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 为每个基表提供谓词 T带列T.C,... : T(T.C,...)
  • 一个 JOIN保存使其参数谓词的 AND 为真的行;对于 UNION ,或;对于 EXCEPT ,与非。
  • SELECT DISTINCT kept columns FROM T保存 EXISTS 删除列的行 [T 的谓词]。
  • T LEFT SEMI JOIN U保存仅存在 U 列的行 [T 的谓词和 U 的谓词]。
  • 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 JOINing 它们之后 ON(对于 INNER JOINs)和 WHERE 过滤掉一些。

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

    关于sql - EXISTS 和 IN 的 Spark 替换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34861516/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com