我如何将此查询编写为联接而不是相关查询?

Posted

技术标签:

【中文标题】我如何将此查询编写为联接而不是相关查询?【英文标题】:How would I write this query as a join instead of a correlated query? 【发布时间】:2015-04-29 17:53:10 【问题描述】:

因此,Netezza 不能在 SELECT 语句中使用相关子查询,不幸的是,在我的特定情况下,我想不出一种方法来避免这种情况。我正在考虑用ROW_NUMBER() 做点什么;但是,我不能在 HAVING 子句中包含窗口函数。

我有以下查询:

select 
    a.*
    ,(  select b.col1
        from b
        where b.ky = a.ky
            and a.date <= b.date
        order by b.date desc
        limit 1
    ) as new_col
from a

有什么建议吗?

【问题讨论】:

我认为你这样做的方式是最好的方式。基本上你要做的是this,除非你可以使用依赖于你正在使用的 DBMS 的 Window 函数,否则它不能通过直接连接来完成。 @Brad:不幸的是,Netezza 不支持我正在尝试做的事情。不过感谢您的链接...我会检查一下。 【参考方案1】:

这应该会返回预期的结果:

select *
from 
 (
   select 
      a.*
     ,b.col1 as b_col1
     ,row_number() 
      over (partition by a.ky
            order by b.date desc NULLS FIRST) as rn 
   from a left join b
   where b.ky = a.ky 
   and a.date <= b.date
 ) as dt
where rn = 1

【讨论】:

关于NULLS FIRST 的快速问题。这是为了防止不存在a.date &lt;= b.date 的行的情况,还是它提供其他功能?根据表格的构造,我实际上可以保证该条件至少在一行中成立。 继续并批准了这个答案,因为它似乎有效,我可能需要几天时间来验证。也就是说,如果您不介意,仍然想知道是否包含 NULLS FIRST 您不需要 NULLS FIRST,只需将其删除即可。如果不存在匹配的行,标量子查询将返回 NULL,但在这种情况下当然没关系。这是我的推理错误。【参考方案2】:

我不确定我是否理解您的问题,但这是您要找的吗?

SELECT TOP 1 a.*, b.col1 FROM a JOIN b ON a.ky = b.ky
WHERE a.date <= b.date ORDER BY b.date desc

【讨论】:

不。那只会选择一行 tbl a。我想将 new_col 附加到 tbl a 中的每条记录。此外,这是使用 ansi-sql 的 Netezza,因此它没有 TOP 语句。 您写的查询是一个选择,您在寻找更新吗?如果是这样,您的表中是否有一列用于保存您要添加的值? 不,不是在寻找更新。试图一起选择一大堆不同的表。这只是一系列 CTE 的一部分。

以上是关于我如何将此查询编写为联接而不是相关查询?的主要内容,如果未能解决你的问题,请参考以下文章

使用内部联接删除

如何将此 Informix 嵌套联接转换为 tsql 嵌套联接?

如何编写包含联接、更新和排序的查询?

如何编写没有联接的 JPA 2.1 更新条件查询?

如何编写带有联接和聚合的 SQLAlchemy 查询?

Arel、联接和 Rails 查询