I'm new to CROSS APPLY and trying to understand the mechanics of exactly how it works. Specifically, in doing some tests, I found that including a GROUP BY clause within the CROSS APPLY statement drastically improves the performance of aggregations, but this seems a bit counter-intuitive. I suppose what's confusing me is the precise order of operations.
Here's my test:
declare @cust table (CUSTID int, NAME varchar(30), MaxOrder decimal, TotalAmountSpent decimal, OrderCount int)
declare @order table (OID int, CUSTID int, AMOUNT decimal)
insert into @cust values (01, 'Fred', 0, 0, 0)
insert into @cust values (02, 'Mary', 0, 0, 0)
insert into @cust values (03, 'Karl', 0, 0, 0)
insert into @order values (20, 01, 6.00)
insert into @order values (21, 03, 10.00)
insert into @order values (22, 03, 20.00)
update @cust
set MaxOrder = app.MaxOrder, TotalAmountSpent = app.TotalAmountSpent, OrderCount = app.OrderCount
from @cust c
cross apply (
select MAX(AMOUNT) MaxOrder, SUM(AMOUNT) TotalAmountSpent, COUNT(OID) OrderCount
from @order o
where c.CUSTID = o.CUSTID
group by o.CUSTID
) app
select * from @cust
This yields correct results:
CUSTID NAME MaxOrder TotalAmountSpent OrderCount
1 Fred 6 6 1
2 Mary 0 0 0
3 Karl 20 30 2
Commenting out the GROUP BY causes Mary's values to be written over as NULL:
CUSTID NAME MaxOrder TotalAmountSpent OrderCount
1 Fred 6 6 1
2 Mary NULL NULL 0
3 Karl 20 30 2
So while both result sets could be regarded as "correct", the first method only affects the rows that are actually relevant. Over a much larger data set, this appears to improve performance quite a bit.
Here's what I'm confused about: In general, I believe that in any SQL statement, the WHERE clause will be processed before a GROUP BY clause, no? In this case, does the SQL Server query optimizer know to execute the GROUP BY first, before applying the WHERE clause between the left and right tables? It surprised me that writing it this way led to both correct results and better performance. An explanation of exactly what's going on under the hood would be much appreciated.
Thanks!