交叉应用聚合

coh*_*ena 6 sql t-sql sql-server sql-server-2012

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

我正在使用Sql Server 2012.

大多数情况下,当我有一个需要我通常使用的派生表的查询时CROSS APPLY.我认为这是更好的性能,同样,我可以访问外部表,所以我可以为每个连接的行执行TOP n等.

今天我遇到了一个非常有趣的交叉应用行为,在我看来它似乎是一个bug.

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

据我所知,如果内部表没有返回任何内容,那么外部表也不会(CROSS APPLYvs 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
Run Code Online (Sandbox Code Playgroud)

所以,问题是:

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

Mar*_*ith 5

CROSS APPLY 如果内部表达式不返回行,则将消除外部行。

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

例如,SELECT COUNT(*) FROM EmptyTable返回带有结果的单行0- 不是没有行。

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