交叉应用聚合

时间:2018-02-08 17:58:32

标签: sql sql-server tsql sql-server-2012

具有聚合函数的CROSS APPLY是否会返回一行,即使内部表达式没有结果?

我正在使用Sql Server 2012。

我大多数时候都有 需要派生表的查询我通常使用CROSS APPLY。 我认为这是更好的表现,同样,我可以访问外部 因此我可以为每个加入的行等执行TOP n

今天我遇到了一个非常有趣的交叉申请行为 在我眼里,这似乎是一个错误。

我试图在某些桌子上进行聚合,但我需要 细节也是如此。所以我编写了没有任何聚合的查询, 我尝试了交叉应用来总结应用表Id相等的位置 外表的id。

据我所知,如果是内表 没有返回任何东西,那么外表也不会(CROSS APPLY vs OUTER APPLY),而且当我不使用时就是这种情况 聚合但是当我使用COUNT函数时 即使内部表没有返回任何内容,我也会得到结果。我尝试过这个 使用简单的临时表(参见代码),令人惊讶的是我得到了同样的结果 结果

如果我做了GROUP BY,它就可以了。

CREATE TABLE #SampleParent (Id INT PRIMARY KEY IDENTITY, ParentName VARCHAR(25))

CREATE TABLE #SampleChildren (Id INT PRIMARY KEY IDENTITY, ParentId INT, ChildName VARCHAR(25))

INSERT INTO #SampleParent
(   ParentName )
VALUES ('Bob')

SELECT * 
FROM #SampleParent AS sp
CROSS APPLY (SELECT sc.ChildName FROM #SampleChildren AS sc WHERE sc.ParentId = sp.Id) c
WHERE sp.Id = 1

SELECT * 
FROM #SampleParent AS sp
CROSS APPLY (SELECT COUNT(sc.ChildName) c FROM #SampleChildren AS sc WHERE sc.ParentId = sp.Id) c
WHERE sp.Id = 1

--GROUP BY
SELECT * 
FROM #SampleParent AS sp
CROSS APPLY (SELECT COUNT(sc.ChildName) c FROM #SampleChildren AS sc WHERE sc.ParentId = sp.Id GROUP BY sc.ParentId) c
WHERE sp.Id = 1

所以,问题是:

具有聚合函数的CROSS APPLY是否会返回一行,即使内部表达式没有结果?

1 个答案:

答案 0 :(得分:4)

如果内部表达式没有返回行,

CROSS APPLY将消除外部行。

没有GROUP BY的聚合是标量聚合(与向量聚合相对)和(在没有HAVING子句的情况下)即使针对空表运行也始终返回一行。

e.g。 SELECT COUNT(*) FROM EmptyTable返回结果为0的单行 - 不是没有行。

因此,这解释了您所询问的行为。