Rad*_*adu 10 sql apache-spark-sql
我试图运行使用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>)
Run Code Online (Sandbox Code Playgroud)
不幸的是,这似乎不受支持.我也尝试用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 ...)
Run Code Online (Sandbox Code Playgroud)
不幸的是,该IN条款似乎也没有得到支持.
有关如何编写实现所需结果的SQL查询的任何想法?我原则上可以将该WHERE条款建模为另一个条款,JOIN而第二个OR条款则可以模拟,UNION但它看起来非常笨拙.
编辑:列出一些可能的解决方案.
解决方案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
Run Code Online (Sandbox Code Playgroud)
解决方案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
Run Code Online (Sandbox Code Playgroud)
phi*_*pxy 16
SparkSQL目前没有EXISTS&IN."(最新)Spark SQL/DataFrames和数据集指南/支持的Hive功能"
始终可以使用JOIN或LEFT SEMI JOIN重写EXISTS&IN."尽管Apache Spark SQL目前不支持IN或EXISTS子查询,但您可以通过重写查询以使用LEFT SEMI JOIN来有效地实现语义." OR总是可以使用UNION重写.AND NOT可以使用EXCEPT重写.
表保存使某些谓词(由列名参数化的语句)为true的行:
T提供带有列的谓词T.C,...:T(TC,...)JOIN保存使其参数的AND'谓词为真的行; 对于a UNION,OR; 为了EXCEPT,AND NOT.SELECT DISTINCTkept columnsFROMT保存EXISTS 删除列的行[ T的谓词 ].TLEFT SEMI JOINU保持EXISTS U-only列的行[ U 的T的谓词和谓词 ].TWHEREcondition保存T AND 条件谓词的行. (重新查询一般会看到这个答案.)
因此,通过记住与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
Run Code Online (Sandbox Code Playgroud)
您的解决方案1没有按照您的想法执行.如果只有一个exists_clause表是空的,即即使另一个表中有ID可用的匹配项,表的FROM交叉产品也是空的,并且不返回任何行.("SQL语义的一个不直观的后果":第6章数据库系统的数据库语言SQL侧栏第264页:完整的第2版.) FROM不只是引入表行的名称,它是CROSS JOINING和/或OUTER加入它们之后ON(对于INNER JOINs)和WHERE过滤掉一些.
对于返回相同行的不同表达式,性能通常是不同的.这取决于DBMS优化.DBMS和/或程序员可能知道的许多细节,如果可能知道或可能不知道,可能或可能不能达到最佳平衡,会影响评估查询的最佳方式以及编写查询的最佳方式.但是在WHERE中每行执行两个ORed子选择(如在原始查询中,但也在您的已解决的解决方案2中)并不一定比运行两个SELECT的UNION更好(如在我的查询中).
| 归档时间: |
|
| 查看次数: |
17195 次 |
| 最近记录: |