APPLY 运算符 - 它如何决定哪些行是两组之间的匹配?

Posted

技术标签:

【中文标题】APPLY 运算符 - 它如何决定哪些行是两组之间的匹配?【英文标题】:APPLY operator - how does it decide which rows are a match between the two sets? 【发布时间】:2021-03-10 18:13:21 【问题描述】:

使用 JOIN 时,很清楚是什么决定了行是否匹配,例如开启 a.SomeID1=b.SomeID1。因此,唯一返回的行将是别名 A 和 B 引用的表中存在匹配“SomeID1”的行。

我最初的想法是,在使用 APPLY 时,WHERE 子句通常放在右侧查询中,以提供与 JOIN 的 ON 子句类似的功能。

但是,我看到许多 SQL 查询在使用 APPLY 时在右侧查询中不包含 WHERE。那么这是否意味着结果行将只是两个表中行数的乘积?

使用 APPLY 时,什么逻辑决定左右查询匹配哪些行?

我尝试了很多博客文章、此处的答案,甚至 YouTube 视频,但没有一个解释让我“点击”。

【问题讨论】:

对数据集中的每一行应用“应用” 你见过这个吗? mssqltips.com/sqlservertip/1958/… 请记住,APPLY 是一个 SQL Server 扩展。你不会在大多数实现中找到它。 理解apply的关键在于它的不匹配,它的apply,它根据现有数据计算新数据,这与加入单独的数据完全不同。 在 APPLY 中,左表的每一行都与作为它的函数的右表交叉连接。 INNER JOIN ON 是 CROSS JOIN WHERE。 CROSS JOIN 是 INNER JOIN ON TRUE。 PS您只是要求另一个不理解的APPLY演示文稿,而我们不知道您不明白什么。阅读权威的介绍/教程/手册并询问 1 个特定研究的非重复问题,其中第一个问题。当您看到意外的示例/结果/输出时,请说出您的预期和原因,并参考引用的权威文档进行说明。 PS找一本教科书。数十人在线。 在考虑发布之前,请阅读手册并在谷歌上搜索任何错误消息以及您的问题/问题/目标的许多清晰、简洁和准确的措辞,包括和不包括您的特定名称/字符串/数字,“网站: ***.com 和标签;阅读许多答案。如果您发布问题,请使用一个短语作为标题。反映你的研究。请参阅How to Ask 和投票箭头鼠标悬停文本。 【参考方案1】:

apply 运算符(在支持它的数据库中)实现了一种称为横向连接join

对我来说,理解它的最佳方式是从相关子查询开始。例如:

select a.*,
       (select count(*) 
        from b
        where b.a_id = a.a_id
--------------^
       ) as b_count
from a;

子查询为a 中的每一行计算b 中匹配的行数。它是如何做到的?相关子句是将子查询映射到外部查询的条件。

Apply 的工作方式相同:

select a.*, b.b_count
from a outer apply
     (select count(*) as b_count
      from b
      where b.a_id = a.a_id
------------^
     ) b;

换句话说,相关子句是您问题的答案。

横向连接相关子查询有什么区别?有以下三个区别:

横向连接可以返回多行。 横向连接可以返回多于一列。 横向连接位于FROM 子句中,因此可以在查询中多次引用返回的列。

【讨论】:

【参考方案2】:

进一步了解 Gordon 的出色回答:

APPLY 不需要相关(即它使用来自外部查询的列),关键是它是横向(它为 每个 行返回一个新结果集)。

所以从基本查询开始:

select c.*
from customer c;

示例结果:

Id Name
1 John
2 Jack

这个想法是应用一个新的结果集。在这种情况下,我们只希望单个行(分组计数)应用于每个现有行。

注意where 相关性,我们使用外部引用

select c.*, o.Orders
from customer c
outer apply
     (select count(*) as Orders
      from [order] o
      where o.c_id = c.id
     ) o;
Id Name Orders
1 John 2
2 Jack 0

但是,我们可以返回多个结果。事实上,我们可以返回任何我们喜欢的东西,并在结果上放置任意过滤器:

select c.*, t.*
from customer c
outer apply
     (select 'Thing1' thing
     union all
     select 'Thing2'
     where c.Name = 'Jack'
     ) t;
Id Name thing
1 John Thing1
1 John Thing2
2 Jack Thing1

请注意包含John 的行是如何根据过滤器加倍的。另请注意,union 的前半部分没有外部引用。

另请参阅 this answer 了解更多 APPLY 技巧。

【讨论】:

以上是关于APPLY 运算符 - 它如何决定哪些行是两组之间的匹配?的主要内容,如果未能解决你的问题,请参考以下文章

1列中2组之间的相关性

CUP主要技术指标包括哪些

R:如何读取固定宽度的数据文件,其中数据连接成两组,堆叠在一个文件的顶部

如何理解皮尔逊相关系数

RandomForestClassifiers sklearn apply(X)

如何理解皮尔逊相关系数